Caldera Forms – More Than Contact Forms - Version 1.0.91

Version Description

(27 July, 2014) =

Download this release

Release Info

Developer Desertsnowman
Plugin Icon 128x128 Caldera Forms – More Than Contact Forms
Version 1.0.91
Comparing to
See all releases

Code changes from version 1.0.0 to 1.0.91

Files changed (97) hide show
  1. README.md +45 -24
  2. assets/css/admin.css +46 -11
  3. assets/css/caldera-alert.css +24 -85
  4. assets/css/caldera-form.css +787 -523
  5. assets/css/caldera-grid.css +0 -2
  6. assets/css/editor-grid.css +7 -1
  7. assets/css/modals.css +8 -2
  8. assets/css/processors-edit.css +3 -0
  9. assets/images/checkmark.png +0 -0
  10. assets/js/conditionals.js +111 -67
  11. assets/js/edit.js +96 -24
  12. assets/js/frontend-script-init.js +71 -2
  13. assets/js/jquery.baldrick.js +2 -2
  14. assets/js/layout-grid.js +345 -75
  15. assets/js/processors-edit.js +34 -10
  16. caldera-core.php +9 -5
  17. classes/admin.php +268 -87
  18. classes/caldera-grid.php +235 -224
  19. classes/core.php +2004 -380
  20. classes/widget.php +8 -2
  21. fields/button/config_template.html +2 -0
  22. fields/button/field.php +12 -1
  23. fields/calculation/config.php +91 -0
  24. fields/calculation/field.php +95 -0
  25. fields/calculation/line-templates.php +197 -0
  26. fields/calculation/preview.php +7 -0
  27. fields/calculation/style.css +6 -0
  28. fields/checkbox/field.php +5 -1
  29. fields/checkbox/preview.php +1 -1
  30. fields/color_picker/field.php +1 -1
  31. fields/color_picker/minicolors.js +1 -1
  32. fields/date_picker/css/datepicker.css +426 -150
  33. fields/date_picker/datepicker.php +1 -1
  34. fields/date_picker/js/bootstrap-datepicker.js +1155 -405
  35. fields/date_picker/setup.html +1 -1
  36. fields/dropdown/field.php +10 -0
  37. fields/email/config.php +12 -0
  38. fields/email/field.php +6 -1
  39. fields/email/preview.php +1 -1
  40. fields/html/config_template.php +1 -1
  41. fields/html/field.php +51 -1
  42. fields/image_picker/js/admin.js +1 -1
  43. fields/paragraph/config_template.html +7 -1
  44. fields/paragraph/field.php +5 -1
  45. fields/paragraph/preview.php +1 -1
  46. fields/phone/config.php +44 -0
  47. fields/phone/field.php +17 -0
  48. fields/phone/masked-input.js +1652 -0
  49. fields/phone/preview.php +7 -0
  50. fields/radio/field.php +5 -1
  51. fields/radio/preview.php +1 -1
  52. fields/range_slider/config.php +99 -0
  53. fields/range_slider/field.php +62 -0
  54. fields/range_slider/preview.php +24 -0
  55. fields/range_slider/rangeslider.css +50 -0
  56. fields/range_slider/rangeslider.js +312 -0
  57. fields/range_slider/rangeslider.min.js +2 -0
  58. fields/star-rate/cf-raty.css +53 -0
  59. fields/star-rate/config.php +61 -0
  60. fields/star-rate/field.php +39 -0
  61. fields/star-rate/fonts/cf-raty.eot +0 -0
  62. fields/star-rate/fonts/cf-raty.svg +23 -0
  63. fields/star-rate/fonts/cf-raty.ttf +0 -0
  64. fields/star-rate/fonts/cf-raty.woff +0 -0
  65. fields/star-rate/fonts/raty.eot +0 -0
  66. fields/star-rate/fonts/raty.svg +15 -0
  67. fields/star-rate/fonts/raty.ttf +0 -0
  68. fields/star-rate/fonts/raty.woff +0 -0
  69. fields/star-rate/images/cancel-off.png +0 -0
  70. fields/star-rate/images/cancel-on.png +0 -0
  71. fields/star-rate/images/star-half.png +0 -0
  72. fields/star-rate/images/star-off.png +0 -0
  73. fields/star-rate/images/star-on.png +0 -0
  74. fields/star-rate/jquery.raty.css +46 -0
  75. fields/star-rate/jquery.raty.js +668 -0
  76. fields/star-rate/preview.php +22 -0
  77. fields/text/config.php +50 -0
  78. fields/text/config_template.html +0 -6
  79. fields/text/field.php +13 -3
  80. fields/text/preview.php +1 -1
  81. fields/toggle_switch/css/setup.css +1 -1
  82. fields/toggle_switch/field.php +8 -0
  83. fields/toggle_switch/js/toggle.js +2 -2
  84. includes/cf-ajax/js/ajax-core.js +61 -0
  85. includes/cf-ajax/plugin.php +181 -0
  86. includes/custom_field_class.php +27 -0
  87. includes/field_processors.php +39 -0
  88. readme.txt +150 -6
  89. ui/admin.php +97 -12
  90. ui/admin_templates.php +198 -10
  91. ui/edit-entry.php +404 -0
  92. ui/edit.php +162 -77
  93. ui/panels/emailer.php +5 -2
  94. ui/panels/layout.php +74 -37
  95. ui/panels/layout_add_row.php +11 -0
  96. ui/panels/pages.php +38 -0
  97. ui/panels/processors.php +14 -7
README.md CHANGED
@@ -7,55 +7,76 @@ WordPress form builder... I'll make a better description later.
7
 
8
  Filters:
9
 
 
 
 
10
  - caldera_forms_get_field_types
11
- - caldera_forms_get_panel_extensions
12
- - caldera_forms_submit_get_form
13
- - caldera_forms_submit_transient
14
- - caldera_forms_submit_error_transient
15
- - caldera_forms_submit_error_transient_required
16
- - caldera_forms_submit_error_redirect
17
- - caldera_forms_submit_error_redirect_required
18
  - caldera_forms_get_form_processors
19
- - caldera_forms_submit_error_transient_pre_process
20
- - caldera_forms_submit_error_redirect_pre_process
21
- - caldera_forms_submit_pre_process
22
- - caldera_forms_submit_process
23
- - caldera_forms_submit_post_process
 
 
 
24
  - caldera_forms_submit_redirect
25
- - caldera_forms_submit_error_redirect_complete
26
  - caldera_forms_render_get_form
27
  - caldera_forms_render_set_grid_size
28
  - caldera_forms_render_grid_settings
29
  - caldera_forms_render_note_general_classes
30
  - caldera_forms_render_note_classes
 
 
31
  - caldera_forms_render_get_transient
 
32
  - caldera_forms_render_field_classes
33
- - caldera_forms_render_field_classes_type-{field-type}
34
- - caldera_forms_render_field_classes_slug-{field-slug}
35
  - caldera_forms_render_get_field
36
- - caldera_forms_render_get_field_type-{field-type}
37
- - caldera_forms_render_get_field_slug-{field-slug}
38
  - caldera_forms_render_field_structure
39
- - caldera_forms_render_field_structure_type-{field-type}
40
- - caldera_forms_render_field_structure_slug-{field-slug}
41
  - caldera_forms_render_field
42
- - caldera_forms_render_field_type-{field-type}
43
- - caldera_forms_render_field_slug-{field-slug}
44
  - caldera_forms_render_grid_structure
45
  - caldera_forms_render_notices
 
46
  - caldera_forms_render_form_classes
 
 
 
 
 
 
 
 
47
 
48
 
49
  Actions:
50
 
 
 
51
  - caldera_forms_submit_start
52
  - caldera_forms_submit_start_processors
53
- - caldera_forms_submit_pre_process
54
- - caldera_forms_submit_process
 
 
55
  - caldera_forms_submit_post_process
 
56
  - caldera_forms_submit_complete
57
- - caldera_forms_submit_redirect
58
  - caldera_forms_render_start
59
  - caldera_forms_render_end
 
 
 
 
 
 
60
 
61
 
7
 
8
  Filters:
9
 
10
+ - caldera_forms_redirect_url
11
+ - caldera_forms_redirect_url_{ type | error, preprocess, complete }
12
+ - caldera_forms_do_magic_tag
13
  - caldera_forms_get_field_types
 
 
 
 
 
 
 
14
  - caldera_forms_get_form_processors
15
+ - caldera_forms_submit_get_form
16
+ - caldera_forms_submit_transient_setup
17
+ - caldera_forms_submit_return_transient
18
+ - caldera_forms_submit_return_transient_required
19
+ - caldera_forms_submit_return_redirect
20
+ - caldera_forms_submit_return_redirect_required
21
+ - caldera_forms_submit_return_transient
22
+ - caldera_forms_submit_return_redirect-{ processor_type }
23
  - caldera_forms_submit_redirect
24
+ - caldera_forms_submit_redirect_complete
25
  - caldera_forms_render_get_form
26
  - caldera_forms_render_set_grid_size
27
  - caldera_forms_render_grid_settings
28
  - caldera_forms_render_note_general_classes
29
  - caldera_forms_render_note_classes
30
+ - caldera_forms_render_pre_get_entry
31
+ - caldera_forms_render_get_entry
32
  - caldera_forms_render_get_transient
33
+ - caldera_forms_render_setup_field
34
  - caldera_forms_render_field_classes
35
+ - caldera_forms_render_field_classes_type-{ field_type }
36
+ - caldera_forms_render_field_classes_slug-{ field_slug }
37
  - caldera_forms_render_get_field
38
+ - caldera_forms_render_get_field_type-{ field_type }
39
+ - caldera_forms_render_get_field_slug-{ field_slug }
40
  - caldera_forms_render_field_structure
41
+ - caldera_forms_render_field_structure_type-{ field_type }
42
+ - caldera_forms_render_field_structure_slug-{ field_slug }
43
  - caldera_forms_render_field
44
+ - caldera_forms_render_field_type-{ field_type }
45
+ - caldera_forms_render_field_slug-{ field_slug }
46
  - caldera_forms_render_grid_structure
47
  - caldera_forms_render_notices
48
+ - caldera_forms_render_form_element
49
  - caldera_forms_render_form_classes
50
+ - caldera_forms_render_form_attributes
51
+ - caldera_forms_render_form
52
+ - caldera_forms_entry_viewer_buttons
53
+ - caldera_forms_get_field_types
54
+ - caldera_forms_view_field_{ field_type }
55
+ - caldera_forms_get_field_types
56
+ - caldera_forms_get_panel_extensions
57
+ - caldera_forms_create_form
58
 
59
 
60
  Actions:
61
 
62
+ - caldera_forms_redirect
63
+ - caldera_forms_redirect_{ type | error, preprocess, complete }
64
  - caldera_forms_submit_start
65
  - caldera_forms_submit_start_processors
66
+ - caldera_forms_submit_pre_process_start
67
+ - caldera_forms_submit_pre_process_end
68
+ - caldera_forms_submit_process_start
69
+ - caldera_forms_submit_process_end
70
  - caldera_forms_submit_post_process
71
+ - caldera_forms_submit_post_process_end
72
  - caldera_forms_submit_complete
 
73
  - caldera_forms_render_start
74
  - caldera_forms_render_end
75
+ - caldera_forms_delete_form
76
+ - caldera_forms_import_form
77
+ - caldera_forms_save_form_register
78
+ - caldera_forms_save_form
79
+ - caldera_forms_save_form_register
80
+ - caldera_forms_create_form
81
 
82
 
assets/css/admin.css CHANGED
@@ -68,12 +68,24 @@
68
  .icn-cf:before {
69
  content: "\e604";
70
  }
 
 
 
 
 
 
 
 
71
  /* Admin Panels */
 
72
  .caldera-editor-header-nav > li.caldera-forms-headtext {
73
  display: block;
74
  padding: 12px 0 0;
75
  color: #737373;
76
  }
 
 
 
77
  .toggle_option_row {
78
  margin: 4px 0;
79
  }
@@ -95,11 +107,13 @@
95
  border-radius: 0;
96
  margin-right: -5px;
97
  }
98
- .toggle_option_tab .button:first-child {
99
- border-radius: 3px 0 0 3px;
100
- }
101
  .toggle_option_tab .button:last-child {
102
- border-radius: 0 3px 3px 0;
 
 
 
 
 
103
  }
104
  .toggle_option_preview .button {
105
  border-radius: 0;
@@ -263,15 +277,17 @@ select.caldera-type-selector {
263
  background-color: #F8F8F8;
264
  top: 85px;
265
  }
266
- .caldera-editor-header .button.caldera-header-save-button {
267
- margin: 5px;
268
- position: absolute;
269
- top: 0;
 
270
  }
271
  .caldera-editor-header-nav {
272
  list-style: none outside none;
273
  margin: 0;
274
  min-height: 38px;
 
275
  }
276
  .caldera-editor-header-nav > li {
277
  float: left;
@@ -404,6 +420,7 @@ li.caldera-editor-logo {
404
  position: absolute;
405
  right: 12px;
406
  top: 12px;
 
407
  }
408
  .layout-form-field.ui-sortable-helper {
409
  border-radius: 3px;
@@ -472,10 +489,16 @@ h3.caldera-editor-field-title {
472
  margin-bottom: 30px;
473
  padding-bottom: 20px;
474
  }
475
- .add-new-h2.caldera-add-group,
476
- .add-new-h2.caldera-add-group:active {
 
 
477
  font-size: 10px;
478
- margin: 4px 30px 4px 10px;
 
 
 
 
479
  }
480
  .caldera-config-group label {
481
  display: block;
@@ -617,6 +640,9 @@ a span.error-tag {
617
  .form-entries-wrap {
618
  padding: 0 30px;
619
  }
 
 
 
620
  .form-panel.postbox {
621
  border-left: 6px solid #E5E5E5;
622
  float: left;
@@ -663,6 +689,15 @@ a span.error-tag {
663
  top: -18px;
664
  width: 28px;
665
  }
 
 
 
 
 
 
 
 
 
666
  .avatar-link .avatar {
667
  max-width: 100%;
668
  max-height: 100%;
68
  .icn-cf:before {
69
  content: "\e604";
70
  }
71
+
72
+ /* cleanup for announcements */
73
+ #wpbody-content > div.updated,
74
+ #wpbody-content > div.error {
75
+ margin: 50px 27px -50px 2px;
76
+ }
77
+
78
+
79
  /* Admin Panels */
80
+
81
  .caldera-editor-header-nav > li.caldera-forms-headtext {
82
  display: block;
83
  padding: 12px 0 0;
84
  color: #737373;
85
  }
86
+ .caldera-editor-header-nav > li.sub-meta-line {
87
+ padding: 9px;
88
+ }
89
  .toggle_option_row {
90
  margin: 4px 0;
91
  }
107
  border-radius: 0;
108
  margin-right: -5px;
109
  }
 
 
 
110
  .toggle_option_tab .button:last-child {
111
+ border-top-right-radius: 3px;
112
+ border-bottom-right-radius: 3px;
113
+ }
114
+ .toggle_option_tab .button:first-child {
115
+ border-top-left-radius: 3px;
116
+ border-bottom-left-radius: 3px;
117
  }
118
  .toggle_option_preview .button {
119
  border-radius: 0;
277
  background-color: #F8F8F8;
278
  top: 85px;
279
  }
280
+ .caldera-editor-header .button.caldera-header-save-button,
281
+ .caldera-editor-header .button.caldera-header-preview-button {
282
+ float: left;
283
+ margin: 7px 12px 0 12px;
284
+ position: relative;
285
  }
286
  .caldera-editor-header-nav {
287
  list-style: none outside none;
288
  margin: 0;
289
  min-height: 38px;
290
+ float: left;
291
  }
292
  .caldera-editor-header-nav > li {
293
  float: left;
420
  position: absolute;
421
  right: 12px;
422
  top: 12px;
423
+ z-index: 999;
424
  }
425
  .layout-form-field.ui-sortable-helper {
426
  border-radius: 3px;
489
  margin-bottom: 30px;
490
  padding-bottom: 20px;
491
  }
492
+ .add-new-h2.caldera-add-page,
493
+ .add-new-h2.caldera-add-row,
494
+ .add-new-h2.caldera-add-row:active,
495
+ .add-new-h2.caldera-add-page:active {
496
  font-size: 10px;
497
+ margin: 4px 10px 4px 10px;
498
+ }
499
+ .add-new-h2.caldera-add-page,
500
+ .add-new-h2.caldera-add-page:active {
501
+ margin-left: 0;
502
  }
503
  .caldera-config-group label {
504
  display: block;
640
  .form-entries-wrap {
641
  padding: 0 30px;
642
  }
643
+ .form-entries-wrap .caldera-forms-entry-exporter{
644
+ margin-top: 1px;
645
+ }
646
  .form-panel.postbox {
647
  border-left: 6px solid #E5E5E5;
648
  float: left;
689
  top: -18px;
690
  width: 28px;
691
  }
692
+ .form-panel .cf-deleted-row td {
693
+ opacity: 0.2;
694
+ }
695
+ .form-panel .cf-deleted-row .view-entry-btn{
696
+ display: none;
697
+ }
698
+ .form-panel .cf-deleted-row td:last-child {
699
+ opacity: 1;
700
+ }
701
  .avatar-link .avatar {
702
  max-width: 100%;
703
  max-height: 100%;
assets/css/caldera-alert.css CHANGED
@@ -1,126 +1,65 @@
1
  .caldera-grid .alert {
2
- padding: 15px;
3
- margin-bottom: 20px;
4
- border: 1px solid transparent;
5
- border-radius: 4px;
6
- }
7
- .caldera-grid .alert h4 {
8
- margin-top: 0;
9
- color: inherit;
10
  }
11
  .caldera-grid .alert .alert-link {
12
  font-weight: bold;
13
  }
14
- .caldera-grid .alert > p,
15
- .caldera-grid .alert > ul {
16
- margin-bottom: 0;
17
- }
18
- .caldera-grid .alert > p + p {
19
- margin-top: 5px;
20
- }
21
  .caldera-grid .alert-dismissable {
22
- padding-right: 35px;
23
- }
24
- .caldera-grid .alert-dismissable .close {
25
- position: relative;
26
- top: -2px;
27
- right: -21px;
28
- color: inherit;
29
  }
30
  .caldera-grid .alert-success {
31
  background-color: #dff0d8;
32
- border-color: #d6e9c6;
33
  color: #3c763d;
34
  }
35
  .caldera-grid .alert-success hr {
36
- border-top-color: #c9e2b3;
37
  }
38
  .caldera-grid .alert-success .alert-link {
39
  color: #2b542c;
40
  }
41
  .caldera-grid .alert-info {
42
  background-color: #d9edf7;
43
- border-color: #bce8f1;
44
  color: #31708f;
45
  }
46
  .caldera-grid .alert-info hr {
47
- border-top-color: #a6e1ec;
48
  }
49
  .caldera-grid .alert-info .alert-link {
50
  color: #245269;
51
  }
52
  .caldera-grid .alert-warning {
53
- background-color: #fcf8e3;
54
- border-color: #faebcc;
55
- color: #8a6d3b;
56
  }
57
  .caldera-grid .alert-warning hr {
58
- border-top-color: #f7e1b5;
59
  }
60
  .caldera-grid .alert-warning .alert-link {
61
- color: #66512c;
62
- }
63
- .caldera-grid .alert-error {
64
- background-color: #f2dede;
65
- border-color: #ebccd1;
66
- color: #a94442;
67
- }
68
- .caldera-grid .alert-error hr {
69
- border-top-color: #e4b9c0;
70
- }
71
- .caldera-grid .alert-error .alert-link {
72
- color: #843534;
73
  }
 
74
  .caldera-grid .alert-danger {
75
  background-color: #f2dede;
76
- border-color: #ebccd1;
77
  color: #a94442;
78
  }
 
79
  .caldera-grid .alert-danger hr {
80
- border-top-color: #e4b9c0;
81
  }
 
82
  .caldera-grid .alert-danger .alert-link {
83
  color: #843534;
84
  }
85
- .caldera-grid .clearfix:before,
86
- .caldera-grid .clearfix:after {
87
- content: " ";
88
- display: table;
89
- }
90
- .caldera-grid .clearfix:after {
91
- clear: both;
92
- }
93
- .caldera-grid .center-block {
94
- display: block;
95
- margin-left: auto;
96
- margin-right: auto;
97
- }
98
- .caldera-grid .pull-right {
99
- float: right !important;
100
- }
101
- .caldera-grid .pull-left {
102
- float: left !important;
103
- }
104
- .caldera-grid .hide {
105
- display: none !important;
106
- }
107
- .caldera-grid .show {
108
- display: block !important;
109
- }
110
- .caldera-grid .invisible {
111
- visibility: hidden;
112
- }
113
- .caldera-grid .text-hide {
114
- font: 0/0 a;
115
- color: transparent;
116
- text-shadow: none;
117
- background-color: transparent;
118
- border: 0;
119
- }
120
- .caldera-grid .hidden {
121
- display: none !important;
122
- visibility: hidden !important;
123
- }
124
- .caldera-grid .affix {
125
- position: fixed;
126
  }
1
  .caldera-grid .alert {
2
+ padding: 8px;
3
+ margin-bottom: 18px;
4
+ border-radius: 2px;
 
 
 
 
 
5
  }
6
  .caldera-grid .alert .alert-link {
7
  font-weight: bold;
8
  }
 
 
 
 
 
 
 
9
  .caldera-grid .alert-dismissable {
10
+ padding-right: 28px;
 
 
 
 
 
 
11
  }
12
  .caldera-grid .alert-success {
13
  background-color: #dff0d8;
14
+ border-color: #a3d48e;
15
  color: #3c763d;
16
  }
17
  .caldera-grid .alert-success hr {
18
+ border-top-color: #93cd7c;
19
  }
20
  .caldera-grid .alert-success .alert-link {
21
  color: #2b542c;
22
  }
23
  .caldera-grid .alert-info {
24
  background-color: #d9edf7;
25
+ border-color: #85c5e5;
26
  color: #31708f;
27
  }
28
  .caldera-grid .alert-info hr {
29
+ border-top-color: #70bbe1;
30
  }
31
  .caldera-grid .alert-info .alert-link {
32
  color: #245269;
33
  }
34
  .caldera-grid .alert-warning {
35
+ background-color: #f9edbe;
36
+ border-color: #f0c36d;
37
+ color: #333333;
38
  }
39
  .caldera-grid .alert-warning hr {
40
+ border-top-color: #eeb956;
41
  }
42
  .caldera-grid .alert-warning .alert-link {
43
+ color: #1a1a1a;
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
+ .caldera-grid .alert-error,
46
  .caldera-grid .alert-danger {
47
  background-color: #f2dede;
48
+ border-color: #d59595;
49
  color: #a94442;
50
  }
51
+ .caldera-grid .alert-error hr,
52
  .caldera-grid .alert-danger hr {
53
+ border-top-color: #ce8383;
54
  }
55
+ .caldera-grid .alert-error .alert-link,
56
  .caldera-grid .alert-danger .alert-link {
57
  color: #843534;
58
  }
59
+ .caldera-grid .alert-success,
60
+ .caldera-grid .alert-info,
61
+ .caldera-grid .alert-warning,
62
+ .caldera-grid .alert-error,
63
+ .caldera-grid .alert-danger {
64
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
assets/css/caldera-form.css CHANGED
@@ -1,383 +1,229 @@
1
- .caldera-grid article,
2
- .caldera-grid aside,
3
- .caldera-grid details,
4
- .caldera-grid figcaption,
5
- .caldera-grid figure,
6
- .caldera-grid footer,
7
- .caldera-grid header,
8
- .caldera-grid hgroup,
9
- .caldera-grid main,
10
- .caldera-grid nav,
11
- .caldera-grid section,
12
- .caldera-grid summary {
13
- display: block;
14
- }
15
- .caldera-grid audio,
16
- .caldera-grid canvas,
17
- .caldera-grid progress,
18
- .caldera-grid video {
19
- display: inline-block;
20
- vertical-align: baseline;
21
- }
22
- .caldera-grid audio:not([controls]) {
23
- display: none;
24
- height: 0;
25
- }
26
- .caldera-grid [hidden],
27
- .caldera-grid template {
28
- display: none;
29
- }
30
- .caldera-grid a {
31
- background: transparent;
32
- }
33
- .caldera-grid a:active,
34
- .caldera-grid a:hover {
35
- outline: 0;
36
- }
37
- .caldera-grid abbr[title] {
38
- border-bottom: 1px dotted;
39
- }
40
- .caldera-grid b,
41
- .caldera-grid strong {
42
- font-weight: bold;
43
- }
44
- .caldera-grid dfn {
45
- font-style: italic;
46
- }
47
- .caldera-grid h1 {
48
- font-size: 2em;
49
- margin: 0.67em 0;
50
- }
51
- .caldera-grid mark {
52
- background: #ff0;
53
- color: #000;
54
- }
55
- .caldera-grid small {
56
- font-size: 80%;
57
- }
58
- .caldera-grid sub,
59
- .caldera-grid sup {
60
- font-size: 75%;
61
- line-height: 0;
62
- position: relative;
63
- vertical-align: baseline;
64
- }
65
- .caldera-grid sup {
66
- top: -0.5em;
67
- }
68
- .caldera-grid sub {
69
- bottom: -0.25em;
70
- }
71
- .caldera-grid img {
72
- border: 0;
73
- }
74
- .caldera-grid svg:not(:root) {
75
- overflow: hidden;
76
- }
77
- .caldera-grid figure {
78
- margin: 1em 40px;
79
- }
80
- .caldera-grid hr {
81
- -moz-box-sizing: content-box;
82
- box-sizing: content-box;
83
- height: 0;
84
- }
85
- .caldera-grid pre {
86
- overflow: auto;
87
- }
88
- .caldera-grid code,
89
- .caldera-grid kbd,
90
- .caldera-grid pre,
91
- .caldera-grid samp {
92
- font-family: monospace, monospace;
93
- font-size: 1em;
94
- }
95
- .caldera-grid button,
96
- .caldera-grid input,
97
- .caldera-grid optgroup,
98
- .caldera-grid select,
99
- .caldera-grid textarea {
100
- color: inherit;
101
- font: inherit;
102
- margin: 0;
103
- }
104
- .caldera-grid button {
105
- overflow: visible;
106
- }
107
- .caldera-grid button,
108
- .caldera-grid select {
109
- text-transform: none;
110
- }
111
- .caldera-grid button,
112
- .caldera-grid html input[type="button"],
113
- .caldera-grid input[type="reset"],
114
- .caldera-grid input[type="submit"] {
115
- -webkit-appearance: button;
116
- cursor: pointer;
117
- }
118
- .caldera-grid button[disabled],
119
- .caldera-grid html input[disabled] {
120
- cursor: default;
121
- }
122
- .caldera-grid button::-moz-focus-inner,
123
- .caldera-grid input::-moz-focus-inner {
124
- border: 0;
125
- padding: 0;
126
- }
127
- .caldera-grid input {
128
- line-height: normal;
129
- }
130
- .caldera-grid input[type="checkbox"],
131
- .caldera-grid input[type="radio"] {
132
- box-sizing: border-box;
133
- padding: 0;
134
- }
135
- .caldera-grid input[type="number"]::-webkit-inner-spin-button,
136
- .caldera-grid input[type="number"]::-webkit-outer-spin-button {
137
- height: auto;
138
- }
139
- .caldera-grid input[type="search"] {
140
- -webkit-appearance: textfield;
141
- -moz-box-sizing: content-box;
142
- -webkit-box-sizing: content-box;
143
- box-sizing: content-box;
144
- }
145
- .caldera-grid input[type="search"]::-webkit-search-cancel-button,
146
- .caldera-grid input[type="search"]::-webkit-search-decoration {
147
- -webkit-appearance: none;
148
- }
149
- .caldera-grid fieldset {
150
- border: 1px solid #c0c0c0;
151
- margin: 0 2px;
152
- padding: 0.35em 0.625em 0.75em;
153
- }
154
- .caldera-grid legend {
155
- border: 0;
156
- padding: 0;
157
- }
158
- .caldera-grid textarea {
159
- overflow: auto;
160
- }
161
- .caldera-grid optgroup {
162
- font-weight: bold;
163
- }
164
- .caldera-grid table {
165
- border-collapse: collapse;
166
- border-spacing: 0;
167
- }
168
- .caldera-grid td,
169
- .caldera-grid th {
170
- padding: 0;
171
- }
172
- .caldera-grid fieldset {
173
- padding: 0;
174
- margin: 0;
175
- border: 0;
176
- min-width: 0;
177
- }
178
  .caldera-grid legend {
179
- display: block;
180
- width: 100%;
181
- padding: 0;
182
- margin-bottom: 20px;
183
- font-size: 21px;
184
- line-height: inherit;
185
- color: #333333;
186
- border: 0;
187
- border-bottom: 1px solid #e5e5e5;
188
- }
189
- .caldera-grid label {
190
- display: inline-block;
191
- margin-bottom: 5px;
192
- font-weight: bold;
193
- }
194
- .caldera-grid input[type="search"] {
195
- -webkit-box-sizing: border-box;
196
- -moz-box-sizing: border-box;
197
- box-sizing: border-box;
198
  }
199
  .caldera-grid input[type="radio"],
200
  .caldera-grid input[type="checkbox"] {
201
- margin: 4px 0 0;
202
- margin-top: 1px \9;
203
- /* IE8-9 */
204
- line-height: normal;
205
- }
206
- .caldera-grid input[type="file"] {
207
- display: block;
208
- }
209
- .caldera-grid input[type="range"] {
210
- display: block;
211
- width: 100%;
212
- }
213
- .caldera-grid select[multiple],
214
- .caldera-grid select[size] {
215
- height: auto;
216
- }
217
- .caldera-grid input[type="file"]:focus,
218
- .caldera-grid input[type="radio"]:focus,
219
- .caldera-grid input[type="checkbox"]:focus {
220
- outline: thin dotted;
221
- outline: 5px auto -webkit-focus-ring-color;
222
- outline-offset: -2px;
223
  }
224
  .caldera-grid output {
225
- display: block;
226
- padding-top: 7px;
227
- font-size: 14px;
228
- line-height: 1.42857143;
229
  color: #555555;
230
  }
231
  .caldera-grid .form-control {
232
- display: block;
233
- width: 100%;
234
- height: 34px;
235
- padding: 6px 12px;
236
- font-size: 14px;
237
- line-height: 1.42857143;
238
- color: #555555;
239
  background-color: #ffffff;
240
- background-image: none;
241
- border: 1px solid #cccccc;
242
- border-radius: 4px;
243
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
244
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
245
- -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
246
- transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
 
 
 
 
 
 
 
247
  }
248
  .caldera-grid .form-control:focus {
249
- border-color: #66afe9;
250
  outline: 0;
251
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
252
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
253
  }
254
- .caldera-grid .form-control::-moz-placeholder {
255
- color: #999999;
256
- opacity: 1;
257
- }
258
- .caldera-grid .form-control:-ms-input-placeholder {
259
- color: #999999;
260
- }
261
- .caldera-grid .form-control::-webkit-input-placeholder {
262
- color: #999999;
263
  }
264
  .caldera-grid .form-control[disabled],
265
  .caldera-grid .form-control[readonly],
266
  .caldera-grid fieldset[disabled] .form-control {
267
- cursor: not-allowed;
268
- background-color: #eeeeee;
269
- opacity: 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  }
271
  .caldera-grid textarea.form-control {
 
272
  height: auto;
273
  }
274
- .caldera-grid input[type="search"] {
275
- -webkit-appearance: none;
 
 
 
 
276
  }
277
- .caldera-grid input[type="date"] {
278
- line-height: 34px;
 
 
 
279
  }
280
- .caldera-grid .form-group {
281
- margin-bottom: 15px;
 
 
 
282
  }
283
  .caldera-grid .radio,
284
  .caldera-grid .checkbox {
285
- display: block;
286
- min-height: 20px;
287
- margin-top: 10px;
288
- margin-bottom: 10px;
289
- padding-left: 20px;
290
- }
291
- .caldera-grid .radio label,
292
- .caldera-grid .checkbox label {
293
- display: inline;
294
- font-weight: normal;
295
- cursor: pointer;
296
  }
 
297
  .caldera-grid .radio input[type="radio"],
298
  .caldera-grid .radio-inline input[type="radio"],
 
299
  .caldera-grid .checkbox input[type="checkbox"],
300
  .caldera-grid .checkbox-inline input[type="checkbox"] {
301
- float: left;
302
- margin-left: -20px;
 
 
 
 
 
 
303
  }
304
- .caldera-grid .radio + .radio,
305
- .caldera-grid .checkbox + .checkbox {
306
- margin-top: -5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  }
308
- .caldera-grid .radio-inline,
309
- .caldera-grid .checkbox-inline {
310
- display: inline-block;
311
- padding-left: 20px;
312
- margin-bottom: 0;
313
- vertical-align: middle;
314
- font-weight: normal;
315
- cursor: pointer;
316
- }
317
- .caldera-grid .radio-inline + .radio-inline,
318
- .caldera-grid .checkbox-inline + .checkbox-inline {
319
- margin-top: 0;
320
- margin-left: 10px;
321
- }
322
- .caldera-grid input[type="radio"][disabled],
323
- .caldera-grid input[type="checkbox"][disabled],
324
- .caldera-grid .radio[disabled],
325
- .caldera-grid .radio-inline[disabled],
326
- .caldera-grid .checkbox[disabled],
327
- .caldera-grid .checkbox-inline[disabled],
328
- .caldera-grid fieldset[disabled] input[type="radio"],
329
- .caldera-grid fieldset[disabled] input[type="checkbox"],
330
- .caldera-grid fieldset[disabled] .radio,
331
- .caldera-grid fieldset[disabled] .radio-inline,
332
- .caldera-grid fieldset[disabled] .checkbox,
333
- .caldera-grid fieldset[disabled] .checkbox-inline {
334
- cursor: not-allowed;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
336
  .caldera-grid .input-sm {
337
- height: 30px;
338
- padding: 5px 10px;
339
  font-size: 12px;
340
  line-height: 1.5;
341
- border-radius: 3px;
342
  }
343
  .caldera-grid select.input-sm {
344
- height: 30px;
345
- line-height: 30px;
346
  }
347
  .caldera-grid textarea.input-sm,
348
  .caldera-grid select[multiple].input-sm {
349
  height: auto;
350
  }
351
  .caldera-grid .input-lg {
352
- height: 46px;
353
- padding: 10px 16px;
354
- font-size: 18px;
355
- line-height: 1.33;
356
- border-radius: 6px;
357
  }
358
  .caldera-grid select.input-lg {
359
- height: 46px;
360
- line-height: 46px;
361
  }
362
  .caldera-grid textarea.input-lg,
363
  .caldera-grid select[multiple].input-lg {
364
  height: auto;
365
  }
366
- .caldera-grid .has-feedback {
367
- position: relative;
368
- }
369
  .caldera-grid .has-feedback .form-control {
370
- padding-right: 42.5px;
371
  }
372
- .caldera-grid .has-feedback .form-control-feedback {
373
- position: absolute;
374
- top: 25px;
375
- right: 0;
376
- display: block;
377
- width: 34px;
378
- height: 34px;
379
- line-height: 34px;
380
- text-align: center;
 
 
 
 
 
 
381
  }
382
  .caldera-grid .has-success .help-block,
383
  .caldera-grid .has-success .control-label,
@@ -405,31 +251,59 @@
405
  .caldera-grid .has-success .form-control-feedback {
406
  color: #3c763d;
407
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  .caldera-grid .has-warning .help-block,
409
  .caldera-grid .has-warning .control-label,
410
  .caldera-grid .has-warning .radio,
411
  .caldera-grid .has-warning .checkbox,
412
  .caldera-grid .has-warning .radio-inline,
413
  .caldera-grid .has-warning .checkbox-inline {
414
- color: #8a6d3b;
415
  }
416
  .caldera-grid .has-warning .form-control {
417
- border-color: #8a6d3b;
418
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
419
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
420
  }
421
  .caldera-grid .has-warning .form-control:focus {
422
- border-color: #66512c;
423
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
424
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
425
  }
426
  .caldera-grid .has-warning .input-group-addon {
427
- color: #8a6d3b;
428
- border-color: #8a6d3b;
429
- background-color: #fcf8e3;
430
  }
431
  .caldera-grid .has-warning .form-control-feedback {
432
- color: #8a6d3b;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433
  }
434
  .caldera-grid .has-error .help-block,
435
  .caldera-grid .has-error .control-label,
@@ -437,34 +311,52 @@
437
  .caldera-grid .has-error .checkbox,
438
  .caldera-grid .has-error .radio-inline,
439
  .caldera-grid .has-error .checkbox-inline {
440
- color: #a94442;
441
  }
442
  .caldera-grid .has-error .form-control {
443
- border-color: #a94442;
444
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
445
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
446
  }
447
  .caldera-grid .has-error .form-control:focus {
448
- border-color: #843534;
449
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
450
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
451
  }
452
  .caldera-grid .has-error .input-group-addon {
453
- color: #a94442;
454
- border-color: #a94442;
455
  background-color: #f2dede;
456
  }
457
  .caldera-grid .has-error .form-control-feedback {
458
- color: #a94442;
459
  }
460
- .caldera-grid .form-control-static {
461
- margin-bottom: 0;
 
 
 
 
 
 
 
 
 
 
 
462
  }
463
  .caldera-grid .help-block {
 
464
  display: block;
465
- margin-top: 5px;
466
- margin-bottom: 10px;
467
- color: #737373;
 
 
 
 
 
 
468
  }
469
  @media (min-width: 768px) {
470
  .caldera-grid .form-inline .form-group {
@@ -477,9 +369,6 @@
477
  width: auto;
478
  vertical-align: middle;
479
  }
480
- .caldera-grid .form-inline .input-group > .form-control {
481
- width: 100%;
482
- }
483
  .caldera-grid .form-inline .control-label {
484
  margin-bottom: 0;
485
  vertical-align: middle;
@@ -489,113 +378,108 @@
489
  display: inline-block;
490
  margin-top: 0;
491
  margin-bottom: 0;
492
- padding-left: 0;
493
  vertical-align: middle;
494
  }
 
 
 
 
495
  .caldera-grid .form-inline .radio input[type="radio"],
496
  .caldera-grid .form-inline .checkbox input[type="checkbox"] {
497
  float: none;
498
  margin-left: 0;
 
499
  }
500
  .caldera-grid .form-inline .has-feedback .form-control-feedback {
501
  top: 0;
502
  }
503
  }
504
- .caldera-grid .form-horizontal .control-label,
505
  .caldera-grid .form-horizontal .radio,
506
  .caldera-grid .form-horizontal .checkbox,
507
  .caldera-grid .form-horizontal .radio-inline,
508
  .caldera-grid .form-horizontal .checkbox-inline {
509
- margin-top: 0;
510
- margin-bottom: 0;
511
- padding-top: 7px;
512
  }
513
  .caldera-grid .form-horizontal .radio,
514
  .caldera-grid .form-horizontal .checkbox {
515
- min-height: 27px;
516
- }
517
- .caldera-grid .form-horizontal .form-group {
518
- margin-left: -15px;
519
- margin-right: -15px;
520
  }
521
  .caldera-grid .form-horizontal .form-control-static {
522
- padding-top: 7px;
 
523
  }
524
  @media (min-width: 768px) {
525
  .caldera-grid .form-horizontal .control-label {
526
- text-align: right;
527
  }
528
  }
529
- .caldera-grid .form-horizontal .has-feedback .form-control-feedback {
530
- top: 0;
531
- right: 15px;
532
- }
533
  .caldera-grid .btn {
534
- display: inline-block;
535
- margin-bottom: 0;
536
- font-weight: normal;
537
- text-align: center;
538
- vertical-align: middle;
539
- cursor: pointer;
540
- background-image: none;
541
- border: 1px solid transparent;
542
- white-space: nowrap;
543
- padding: 6px 12px;
544
- font-size: 14px;
545
- line-height: 1.42857143;
546
- border-radius: 4px;
547
- -webkit-user-select: none;
548
- -moz-user-select: none;
549
- -ms-user-select: none;
550
- user-select: none;
551
- }
552
- .caldera-grid .btn:focus,
553
- .caldera-grid .btn:active:focus,
554
- .caldera-grid .btn.active:focus {
555
- outline: thin dotted;
556
- outline: 5px auto -webkit-focus-ring-color;
557
- outline-offset: -2px;
558
- }
559
- .caldera-grid .btn:hover,
560
- .caldera-grid .btn:focus {
561
- color: #333333;
562
- text-decoration: none;
563
  }
564
  .caldera-grid .btn:active,
565
  .caldera-grid .btn.active {
566
- outline: 0;
567
- background-image: none;
568
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
569
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
570
- }
571
- .caldera-grid .btn.disabled,
572
- .caldera-grid .btn[disabled],
573
- .caldera-grid fieldset[disabled] .btn {
574
- cursor: not-allowed;
575
- pointer-events: none;
576
- opacity: 0.65;
577
- filter: alpha(opacity=65);
578
- -webkit-box-shadow: none;
579
- box-shadow: none;
580
  }
581
  .caldera-grid .btn-default {
 
582
  color: #333333;
583
- background-color: #ffffff;
584
- border-color: #cccccc;
 
 
 
 
 
 
 
 
 
 
 
585
  }
586
  .caldera-grid .btn-default:hover,
587
  .caldera-grid .btn-default:focus,
588
  .caldera-grid .btn-default:active,
589
  .caldera-grid .btn-default.active,
590
- .caldera-grid .open .dropdown-toggle.btn-default {
591
  color: #333333;
592
- background-color: #ebebeb;
593
- border-color: #adadad;
 
 
 
 
 
594
  }
595
  .caldera-grid .btn-default:active,
596
  .caldera-grid .btn-default.active,
597
- .caldera-grid .open .dropdown-toggle.btn-default {
598
- background-image: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
599
  }
600
  .caldera-grid .btn-default.disabled,
601
  .caldera-grid .btn-default[disabled],
@@ -612,31 +496,112 @@
612
  .caldera-grid .btn-default.disabled.active,
613
  .caldera-grid .btn-default[disabled].active,
614
  .caldera-grid fieldset[disabled] .btn-default.active {
615
- background-color: #ffffff;
616
- border-color: #cccccc;
 
 
 
 
 
 
 
617
  }
618
  .caldera-grid .btn-default .badge {
619
- color: #ffffff;
620
  background-color: #333333;
621
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
  .caldera-grid .btn-primary {
 
623
  color: #ffffff;
624
- background-color: #428bca;
625
- border-color: #357ebd;
 
 
 
 
 
 
 
 
 
626
  }
627
  .caldera-grid .btn-primary:hover,
628
  .caldera-grid .btn-primary:focus,
629
  .caldera-grid .btn-primary:active,
630
  .caldera-grid .btn-primary.active,
631
- .caldera-grid .open .dropdown-toggle.btn-primary {
632
  color: #ffffff;
633
- background-color: #3276b1;
634
- border-color: #285e8e;
 
 
 
 
 
635
  }
636
  .caldera-grid .btn-primary:active,
637
  .caldera-grid .btn-primary.active,
638
- .caldera-grid .open .dropdown-toggle.btn-primary {
639
- background-image: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
640
  }
641
  .caldera-grid .btn-primary.disabled,
642
  .caldera-grid .btn-primary[disabled],
@@ -653,31 +618,66 @@
653
  .caldera-grid .btn-primary.disabled.active,
654
  .caldera-grid .btn-primary[disabled].active,
655
  .caldera-grid fieldset[disabled] .btn-primary.active {
656
- background-color: #428bca;
657
- border-color: #357ebd;
 
 
 
 
 
 
 
658
  }
659
  .caldera-grid .btn-primary .badge {
660
- color: #428bca;
661
  background-color: #ffffff;
662
  }
663
  .caldera-grid .btn-success {
 
664
  color: #ffffff;
665
- background-color: #5cb85c;
666
- border-color: #4cae4c;
 
 
 
 
 
 
 
 
 
667
  }
668
  .caldera-grid .btn-success:hover,
669
  .caldera-grid .btn-success:focus,
670
  .caldera-grid .btn-success:active,
671
  .caldera-grid .btn-success.active,
672
- .caldera-grid .open .dropdown-toggle.btn-success {
673
  color: #ffffff;
674
- background-color: #47a447;
675
- border-color: #398439;
 
 
 
 
 
676
  }
677
  .caldera-grid .btn-success:active,
678
  .caldera-grid .btn-success.active,
679
- .caldera-grid .open .dropdown-toggle.btn-success {
680
- background-image: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
681
  }
682
  .caldera-grid .btn-success.disabled,
683
  .caldera-grid .btn-success[disabled],
@@ -694,31 +694,66 @@
694
  .caldera-grid .btn-success.disabled.active,
695
  .caldera-grid .btn-success[disabled].active,
696
  .caldera-grid fieldset[disabled] .btn-success.active {
697
- background-color: #5cb85c;
698
- border-color: #4cae4c;
 
 
 
 
 
 
 
699
  }
700
  .caldera-grid .btn-success .badge {
701
- color: #5cb85c;
702
  background-color: #ffffff;
703
  }
704
  .caldera-grid .btn-info {
 
705
  color: #ffffff;
706
- background-color: #5bc0de;
707
- border-color: #46b8da;
 
 
 
 
 
 
 
 
 
708
  }
709
  .caldera-grid .btn-info:hover,
710
  .caldera-grid .btn-info:focus,
711
  .caldera-grid .btn-info:active,
712
  .caldera-grid .btn-info.active,
713
- .caldera-grid .open .dropdown-toggle.btn-info {
714
  color: #ffffff;
715
- background-color: #39b3d7;
716
- border-color: #269abc;
 
 
 
 
 
717
  }
718
  .caldera-grid .btn-info:active,
719
  .caldera-grid .btn-info.active,
720
- .caldera-grid .open .dropdown-toggle.btn-info {
721
- background-image: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
722
  }
723
  .caldera-grid .btn-info.disabled,
724
  .caldera-grid .btn-info[disabled],
@@ -735,31 +770,66 @@
735
  .caldera-grid .btn-info.disabled.active,
736
  .caldera-grid .btn-info[disabled].active,
737
  .caldera-grid fieldset[disabled] .btn-info.active {
 
 
 
 
 
 
738
  background-color: #5bc0de;
739
- border-color: #46b8da;
 
740
  }
741
  .caldera-grid .btn-info .badge {
742
- color: #5bc0de;
743
  background-color: #ffffff;
744
  }
745
  .caldera-grid .btn-warning {
 
746
  color: #ffffff;
747
- background-color: #f0ad4e;
748
- border-color: #eea236;
 
 
 
 
 
 
 
 
 
749
  }
750
  .caldera-grid .btn-warning:hover,
751
  .caldera-grid .btn-warning:focus,
752
  .caldera-grid .btn-warning:active,
753
  .caldera-grid .btn-warning.active,
754
- .caldera-grid .open .dropdown-toggle.btn-warning {
755
  color: #ffffff;
756
- background-color: #ed9c28;
757
- border-color: #d58512;
 
 
 
 
 
758
  }
759
  .caldera-grid .btn-warning:active,
760
  .caldera-grid .btn-warning.active,
761
- .caldera-grid .open .dropdown-toggle.btn-warning {
762
- background-image: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
763
  }
764
  .caldera-grid .btn-warning.disabled,
765
  .caldera-grid .btn-warning[disabled],
@@ -776,31 +846,66 @@
776
  .caldera-grid .btn-warning.disabled.active,
777
  .caldera-grid .btn-warning[disabled].active,
778
  .caldera-grid fieldset[disabled] .btn-warning.active {
779
- background-color: #f0ad4e;
780
- border-color: #eea236;
 
 
 
 
 
 
 
781
  }
782
  .caldera-grid .btn-warning .badge {
783
- color: #f0ad4e;
784
  background-color: #ffffff;
785
  }
786
  .caldera-grid .btn-danger {
 
787
  color: #ffffff;
788
- background-color: #d9534f;
789
- border-color: #d43f3a;
 
 
 
 
 
 
 
 
 
790
  }
791
  .caldera-grid .btn-danger:hover,
792
  .caldera-grid .btn-danger:focus,
793
  .caldera-grid .btn-danger:active,
794
  .caldera-grid .btn-danger.active,
795
- .caldera-grid .open .dropdown-toggle.btn-danger {
796
  color: #ffffff;
797
- background-color: #d2322d;
798
- border-color: #ac2925;
 
 
 
 
 
799
  }
800
  .caldera-grid .btn-danger:active,
801
  .caldera-grid .btn-danger.active,
802
- .caldera-grid .open .dropdown-toggle.btn-danger {
803
- background-image: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  }
805
  .caldera-grid .btn-danger.disabled,
806
  .caldera-grid .btn-danger[disabled],
@@ -817,18 +922,22 @@
817
  .caldera-grid .btn-danger.disabled.active,
818
  .caldera-grid .btn-danger[disabled].active,
819
  .caldera-grid fieldset[disabled] .btn-danger.active {
820
- background-color: #d9534f;
821
- border-color: #d43f3a;
 
 
 
 
 
 
 
822
  }
823
  .caldera-grid .btn-danger .badge {
824
- color: #d9534f;
825
  background-color: #ffffff;
826
  }
827
  .caldera-grid .btn-link {
828
- color: #428bca;
829
- font-weight: normal;
830
- cursor: pointer;
831
- border-radius: 0;
832
  }
833
  .caldera-grid .btn-link,
834
  .caldera-grid .btn-link:active,
@@ -846,34 +955,37 @@
846
  }
847
  .caldera-grid .btn-link:hover,
848
  .caldera-grid .btn-link:focus {
849
- color: #2a6496;
850
- text-decoration: underline;
851
  background-color: transparent;
 
 
852
  }
853
  .caldera-grid .btn-link[disabled]:hover,
854
  .caldera-grid fieldset[disabled] .btn-link:hover,
855
  .caldera-grid .btn-link[disabled]:focus,
856
  .caldera-grid fieldset[disabled] .btn-link:focus {
857
- color: #999999;
858
- text-decoration: none;
859
  }
860
- .caldera-grid .btn-lg {
861
- padding: 10px 16px;
862
- font-size: 18px;
863
- line-height: 1.33;
864
- border-radius: 6px;
 
865
  }
866
- .caldera-grid .btn-sm {
867
- padding: 5px 10px;
 
868
  font-size: 12px;
869
  line-height: 1.5;
870
- border-radius: 3px;
871
  }
872
- .caldera-grid .btn-xs {
873
- padding: 1px 5px;
874
- font-size: 12px;
875
- line-height: 1.5;
876
- border-radius: 3px;
 
877
  }
878
  .caldera-grid .btn-block {
879
  display: block;
@@ -889,48 +1001,200 @@
889
  .caldera-grid input[type="button"].btn-block {
890
  width: 100%;
891
  }
892
- .caldera-grid .clearfix:before,
893
- .caldera-grid .clearfix:after,
894
- .caldera-grid .form-horizontal .form-group:before,
895
- .caldera-grid .form-horizontal .form-group:after {
896
- content: " ";
897
- display: table;
898
  }
899
- .caldera-grid .clearfix:after,
900
- .caldera-grid .form-horizontal .form-group:after {
901
- clear: both;
902
  }
903
- .caldera-grid .center-block {
904
- display: block;
905
- margin-left: auto;
906
- margin-right: auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
907
  }
908
- .caldera-grid .pull-right {
909
- float: right !important;
 
 
 
910
  }
911
- .caldera-grid .pull-left {
912
- float: left !important;
 
 
 
913
  }
914
- .caldera-grid .hide {
915
- display: none !important;
 
 
 
916
  }
917
- .caldera-grid .show {
918
- display: block !important;
 
 
 
919
  }
920
- .caldera-grid .invisible {
921
- visibility: hidden;
 
 
 
922
  }
923
- .caldera-grid .text-hide {
924
- font: 0/0 a;
925
- color: transparent;
926
- text-shadow: none;
927
- background-color: transparent;
928
- border: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
929
  }
930
- .caldera-grid .hidden {
931
- display: none !important;
932
- visibility: hidden !important;
 
933
  }
934
- .caldera-grid .affix {
935
- position: fixed;
 
936
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  .caldera-grid legend {
2
+ margin-bottom: 18px;
3
+ font-size: 19.5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
  .caldera-grid input[type="radio"],
6
  .caldera-grid input[type="checkbox"] {
7
+ margin: 2px 0 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
9
  .caldera-grid output {
10
+ padding-top: 6px;
11
+ font-size: 13px;
12
+ line-height: 1.4;
 
13
  color: #555555;
14
  }
15
  .caldera-grid .form-control {
16
+ height: 30px;
17
+ padding: 5px 8px;
18
+ font-size: 13px;
19
+ line-height: 1.4;
 
 
 
20
  background-color: #ffffff;
21
+ border: 1px solid #d9d9d9;
22
+ border-top-color: #c0c0c0;
23
+ border-radius: 1px;
24
+ -webkit-box-shadow: none;
25
+ box-shadow: none;
26
+ -webkit-transition: none;
27
+ transition: none;
28
+ -webkit-appearance: none;
29
+ }
30
+ .caldera-grid .form-control:hover {
31
+ border: 1px solid #b9b9b9;
32
+ border-top-color: #a0a0a0;
33
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
34
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
35
  }
36
  .caldera-grid .form-control:focus {
37
+ border-color: #999999;
38
  outline: 0;
39
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(153, 153, 153, 0.6);
40
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(153, 153, 153, 0.6);
41
  }
42
+ .caldera-grid .form-control:focus {
43
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
44
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
 
 
 
 
 
 
45
  }
46
  .caldera-grid .form-control[disabled],
47
  .caldera-grid .form-control[readonly],
48
  .caldera-grid fieldset[disabled] .form-control {
49
+ background-color: #f1f1f1;
50
+ border: 1px solid #e5e5e5;
51
+ }
52
+ .caldera-grid .form-control[disabled]:hover,
53
+ .caldera-grid .form-control[readonly]:hover,
54
+ .caldera-grid fieldset[disabled] .form-control:hover,
55
+ .caldera-grid .form-control[disabled]:focus,
56
+ .caldera-grid .form-control[readonly]:focus,
57
+ .caldera-grid fieldset[disabled] .form-control:focus,
58
+ .caldera-grid .form-control[disabled]:active,
59
+ .caldera-grid .form-control[readonly]:active,
60
+ .caldera-grid fieldset[disabled] .form-control:active {
61
+ border: 1px solid #e5e5e5;
62
+ -webkit-box-shadow: none;
63
+ box-shadow: none;
64
+ }
65
+ .caldera-grid .form-control[readonly] .form-control {
66
+ border: 1px solid #d9d9d9;
67
+ }
68
+ .caldera-grid .form-control[readonly] .form-control:hover,
69
+ .caldera-grid .form-control[readonly] .form-control:focus,
70
+ .caldera-grid .form-control[readonly] .form-control:active {
71
+ border: 1px solid #d9d9d9;
72
  }
73
  .caldera-grid textarea.form-control {
74
+ padding-right: 4px;
75
  height: auto;
76
  }
77
+ .caldera-grid input[type="date"],
78
+ .caldera-grid input[type="time"],
79
+ .caldera-grid input[type="datetime-local"],
80
+ .caldera-grid input[type="month"] {
81
+ line-height: 30px;
82
+ line-height: 1.4 \0;
83
  }
84
+ .caldera-grid input[type="date"].input-sm,
85
+ .caldera-grid input[type="time"].input-sm,
86
+ .caldera-grid input[type="datetime-local"].input-sm,
87
+ .caldera-grid input[type="month"].input-sm {
88
+ line-height: 26px;
89
  }
90
+ .caldera-grid input[type="date"].input-lg,
91
+ .caldera-grid input[type="time"].input-lg,
92
+ .caldera-grid input[type="datetime-local"].input-lg,
93
+ .caldera-grid input[type="month"].input-lg {
94
+ line-height: 38px;
95
  }
96
  .caldera-grid .radio,
97
  .caldera-grid .checkbox {
98
+ min-height: 18px;
 
 
 
 
 
 
 
 
 
 
99
  }
100
+ .caldera-grid input[type="radio"],
101
  .caldera-grid .radio input[type="radio"],
102
  .caldera-grid .radio-inline input[type="radio"],
103
+ .caldera-grid input[type="checkbox"],
104
  .caldera-grid .checkbox input[type="checkbox"],
105
  .caldera-grid .checkbox-inline input[type="checkbox"] {
106
+ position: relative;
107
+ width: 13px;
108
+ height: 13px;
109
+ background: white;
110
+ border: 1px solid #dcdcdc;
111
+ border-radius: 1px;
112
+ -webkit-appearance: none;
113
+ border-width: 0 \0;
114
  }
115
+ .caldera-grid input[type="radio"]:focus,
116
+ .caldera-grid .radio input[type="radio"]:focus,
117
+ .caldera-grid .radio-inline input[type="radio"]:focus,
118
+ .caldera-grid input[type="checkbox"]:focus,
119
+ .caldera-grid .checkbox input[type="checkbox"]:focus,
120
+ .caldera-grid .checkbox-inline input[type="checkbox"]:focus {
121
+ outline: 0;
122
+ border-color: #c6c6c6;
123
+ }
124
+ .caldera-grid input[type="radio"]:active,
125
+ .caldera-grid .radio input[type="radio"]:active,
126
+ .caldera-grid .radio-inline input[type="radio"]:active,
127
+ .caldera-grid input[type="checkbox"]:active,
128
+ .caldera-grid .checkbox input[type="checkbox"]:active,
129
+ .caldera-grid .checkbox-inline input[type="checkbox"]:active {
130
+ border-color: #c6c6c6;
131
+ background-color: #ebebeb;
132
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffffffff', GradientType=0);
133
  }
134
+ .caldera-grid input[type="radio"]:checked,
135
+ .caldera-grid .radio input[type="radio"]:checked,
136
+ .caldera-grid .radio-inline input[type="radio"]:checked,
137
+ .caldera-grid input[type="checkbox"]:checked,
138
+ .caldera-grid .checkbox input[type="checkbox"]:checked,
139
+ .caldera-grid .checkbox-inline input[type="checkbox"]:checked {
140
+ background: #fff;
141
+ }
142
+ .caldera-grid input[type="radio"],
143
+ .caldera-grid .radio input[type="radio"],
144
+ .caldera-grid .radio-inline input[type="radio"] {
145
+ border-radius: 1em;
146
+ width: 15px;
147
+ height: 15px;
148
+ }
149
+ .caldera-grid input[type="radio"]:checked::after,
150
+ .caldera-grid .radio input[type="radio"]:checked::after,
151
+ .caldera-grid .radio-inline input[type="radio"]:checked::after {
152
+ content: '';
153
+ display: block;
154
+ position: relative;
155
+ top: 3px;
156
+ left: 3px;
157
+ width: 7px;
158
+ height: 7px;
159
+ background: #666;
160
+ border-radius: 1em;
161
+ }
162
+ .caldera-grid input[type="checkbox"]:hover,
163
+ .caldera-grid .checkbox input[type="checkbox"]:hover,
164
+ .caldera-grid .checkbox-inline input[type="checkbox"]:hover {
165
+ border-color: #c6c6c6;
166
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
167
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
168
+ box-shadow: none \9;
169
+ }
170
+ .caldera-grid input[type="checkbox"]:checked::after,
171
+ .caldera-grid .checkbox input[type="checkbox"]:checked::after,
172
+ .caldera-grid .checkbox-inline input[type="checkbox"]:checked::after {
173
+ content: url(../images/checkmark.png);
174
+ display: block;
175
+ position: absolute;
176
+ top: -6px;
177
+ left: -5px;
178
  }
179
  .caldera-grid .input-sm {
180
+ height: 26px;
181
+ padding: 3px 8px;
182
  font-size: 12px;
183
  line-height: 1.5;
184
+ border-radius: 1px;
185
  }
186
  .caldera-grid select.input-sm {
187
+ height: 26px;
188
+ line-height: 26px;
189
  }
190
  .caldera-grid textarea.input-sm,
191
  .caldera-grid select[multiple].input-sm {
192
  height: auto;
193
  }
194
  .caldera-grid .input-lg {
195
+ height: 38px;
196
+ padding: 9px 14px;
197
+ font-size: 14px;
198
+ line-height: 1.3;
199
+ border-radius: 1px;
200
  }
201
  .caldera-grid select.input-lg {
202
+ height: 38px;
203
+ line-height: 38px;
204
  }
205
  .caldera-grid textarea.input-lg,
206
  .caldera-grid select[multiple].input-lg {
207
  height: auto;
208
  }
 
 
 
209
  .caldera-grid .has-feedback .form-control {
210
+ padding-right: 37.5px;
211
  }
212
+ .caldera-grid .form-control-feedback {
213
+ top: 23px;
214
+ width: 30px;
215
+ height: 30px;
216
+ line-height: 30px;
217
+ }
218
+ .caldera-grid .input-lg + .form-control-feedback {
219
+ width: 38px;
220
+ height: 38px;
221
+ line-height: 38px;
222
+ }
223
+ .caldera-grid .input-sm + .form-control-feedback {
224
+ width: 26px;
225
+ height: 26px;
226
+ line-height: 26px;
227
  }
228
  .caldera-grid .has-success .help-block,
229
  .caldera-grid .has-success .control-label,
251
  .caldera-grid .has-success .form-control-feedback {
252
  color: #3c763d;
253
  }
254
+ .caldera-grid .has-success .form-control {
255
+ -webkit-box-shadow: none;
256
+ box-shadow: none;
257
+ }
258
+ .caldera-grid .has-success .form-control:hover {
259
+ border-color: #3c763d;
260
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
261
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
262
+ }
263
+ .caldera-grid .has-success .form-control:focus {
264
+ border-color: #3c763d;
265
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset;
266
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset;
267
+ }
268
  .caldera-grid .has-warning .help-block,
269
  .caldera-grid .has-warning .control-label,
270
  .caldera-grid .has-warning .radio,
271
  .caldera-grid .has-warning .checkbox,
272
  .caldera-grid .has-warning .radio-inline,
273
  .caldera-grid .has-warning .checkbox-inline {
274
+ color: #e09b17;
275
  }
276
  .caldera-grid .has-warning .form-control {
277
+ border-color: #e09b17;
278
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
279
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
280
  }
281
  .caldera-grid .has-warning .form-control:focus {
282
+ border-color: #b27b12;
283
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f0c36d;
284
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f0c36d;
285
  }
286
  .caldera-grid .has-warning .input-group-addon {
287
+ color: #e09b17;
288
+ border-color: #e09b17;
289
+ background-color: #f9edbe;
290
  }
291
  .caldera-grid .has-warning .form-control-feedback {
292
+ color: #e09b17;
293
+ }
294
+ .caldera-grid .has-warning .form-control {
295
+ -webkit-box-shadow: none;
296
+ box-shadow: none;
297
+ }
298
+ .caldera-grid .has-warning .form-control:hover {
299
+ border-color: #e09b17;
300
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
301
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
302
+ }
303
+ .caldera-grid .has-warning .form-control:focus {
304
+ border-color: #e09b17;
305
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset;
306
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset;
307
  }
308
  .caldera-grid .has-error .help-block,
309
  .caldera-grid .has-error .control-label,
311
  .caldera-grid .has-error .checkbox,
312
  .caldera-grid .has-error .radio-inline,
313
  .caldera-grid .has-error .checkbox-inline {
314
+ color: #dd4b39;
315
  }
316
  .caldera-grid .has-error .form-control {
317
+ border-color: #dd4b39;
318
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
319
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
320
  }
321
  .caldera-grid .has-error .form-control:focus {
322
+ border-color: #c23321;
323
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ec9a90;
324
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ec9a90;
325
  }
326
  .caldera-grid .has-error .input-group-addon {
327
+ color: #dd4b39;
328
+ border-color: #dd4b39;
329
  background-color: #f2dede;
330
  }
331
  .caldera-grid .has-error .form-control-feedback {
332
+ color: #dd4b39;
333
  }
334
+ .caldera-grid .has-error .form-control {
335
+ -webkit-box-shadow: none;
336
+ box-shadow: none;
337
+ }
338
+ .caldera-grid .has-error .form-control:hover {
339
+ border-color: #dd4b39;
340
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
341
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
342
+ }
343
+ .caldera-grid .has-error .form-control:focus {
344
+ border-color: #dd4b39;
345
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset;
346
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset;
347
  }
348
  .caldera-grid .help-block {
349
+ color: #777777;
350
  display: block;
351
+ }
352
+ .caldera-grid .control-label {
353
+ display: block;
354
+ line-height: 1.5em;
355
+ }
356
+ .caldera-grid .form-horizontal .control-label,
357
+ .caldera-grid .form-horizontal .radio-inline,
358
+ .caldera-grid .form-horizontal .checkbox-inline {
359
+ padding-top: 5px;
360
  }
361
  @media (min-width: 768px) {
362
  .caldera-grid .form-inline .form-group {
369
  width: auto;
370
  vertical-align: middle;
371
  }
 
 
 
372
  .caldera-grid .form-inline .control-label {
373
  margin-bottom: 0;
374
  vertical-align: middle;
378
  display: inline-block;
379
  margin-top: 0;
380
  margin-bottom: 0;
 
381
  vertical-align: middle;
382
  }
383
+ .caldera-grid .form-inline .radio label,
384
+ .caldera-grid .form-inline .checkbox label {
385
+ padding-left: 0;
386
+ }
387
  .caldera-grid .form-inline .radio input[type="radio"],
388
  .caldera-grid .form-inline .checkbox input[type="checkbox"] {
389
  float: none;
390
  margin-left: 0;
391
+ margin-bottom: -2px;
392
  }
393
  .caldera-grid .form-inline .has-feedback .form-control-feedback {
394
  top: 0;
395
  }
396
  }
 
397
  .caldera-grid .form-horizontal .radio,
398
  .caldera-grid .form-horizontal .checkbox,
399
  .caldera-grid .form-horizontal .radio-inline,
400
  .caldera-grid .form-horizontal .checkbox-inline {
401
+ padding-top: 6px;
 
 
402
  }
403
  .caldera-grid .form-horizontal .radio,
404
  .caldera-grid .form-horizontal .checkbox {
405
+ min-height: 24px;
 
 
 
 
406
  }
407
  .caldera-grid .form-horizontal .form-control-static {
408
+ padding-top: 6px;
409
+ padding-bottom: 6px;
410
  }
411
  @media (min-width: 768px) {
412
  .caldera-grid .form-horizontal .control-label {
413
+ padding-top: 6px;
414
  }
415
  }
 
 
 
 
416
  .caldera-grid .btn {
417
+ cursor: default;
418
+ background-clip: border-box;
419
+ padding: 5px 12px;
420
+ font-size: 13px;
421
+ line-height: 18px;
422
+ border-radius: 2px;
423
+ -webkit-box-shadow: none;
424
+ box-shadow: none;
425
+ }
426
+ .caldera-grid .btn:hover {
427
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
428
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  }
430
  .caldera-grid .btn:active,
431
  .caldera-grid .btn.active {
432
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
433
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
434
  }
435
  .caldera-grid .btn-default {
436
+ border: 1px solid #dcdcdc;
437
  color: #333333;
438
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #f1f1f1 100%);
439
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #f1f1f1 100%);
440
+ background-repeat: repeat-x;
441
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff1f1f1', GradientType=0);
442
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
443
+ text-shadow: 0 1px rgba(0, 0, 0, 0.1);
444
+ background-color: #f3f3f3;
445
+ text-shadow: 0 1px 0 #fff;
446
+ }
447
+ .caldera-grid .btn-default:hover {
448
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
449
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
450
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
451
  }
452
  .caldera-grid .btn-default:hover,
453
  .caldera-grid .btn-default:focus,
454
  .caldera-grid .btn-default:active,
455
  .caldera-grid .btn-default.active,
456
+ .caldera-grid .open > .dropdown-toggle.btn-default {
457
  color: #333333;
458
+ border: 1px solid #cfcfcf;
459
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e4e4e4 100%);
460
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #e4e4e4 100%);
461
+ background-repeat: repeat-x;
462
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe4e4e4', GradientType=0);
463
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
464
+ background-color: #e4e4e4;
465
  }
466
  .caldera-grid .btn-default:active,
467
  .caldera-grid .btn-default.active,
468
+ .caldera-grid .open > .dropdown-toggle.btn-default {
469
+ border: 1px solid #c3c3c3;
470
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
471
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #d8d8d8 100%);
472
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #d8d8d8 100%);
473
+ background-repeat: repeat-x;
474
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffd8d8d8', GradientType=0);
475
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
476
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
477
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
478
+ }
479
+ .caldera-grid .btn-default:focus {
480
+ border: 1px solid #dcdcdc;
481
+ -webkit-box-shadow: inset 0 0 0 1px #ffffff;
482
+ box-shadow: inset 0 0 0 1px #ffffff;
483
  }
484
  .caldera-grid .btn-default.disabled,
485
  .caldera-grid .btn-default[disabled],
496
  .caldera-grid .btn-default.disabled.active,
497
  .caldera-grid .btn-default[disabled].active,
498
  .caldera-grid fieldset[disabled] .btn-default.active {
499
+ border: 1px solid #dcdcdc;
500
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #f1f1f1 100%);
501
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #f1f1f1 100%);
502
+ background-repeat: repeat-x;
503
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff1f1f1', GradientType=0);
504
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
505
+ background-color: #f5f5f5;
506
+ -webkit-box-shadow: none;
507
+ box-shadow: none;
508
  }
509
  .caldera-grid .btn-default .badge {
510
+ color: #dcdcdc;
511
  background-color: #333333;
512
  }
513
+ .caldera-grid .btn-default:hover {
514
+ text-shadow: none;
515
+ border-color: #c6c6c6;
516
+ background-image: -webkit-linear-gradient(top, #f8f8f8 0%, #f1f1f1 100%);
517
+ background-image: linear-gradient(to bottom, #f8f8f8 0%, #f1f1f1 100%);
518
+ background-repeat: repeat-x;
519
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff8f8f8', endColorstr='#fff1f1f1', GradientType=0);
520
+ background-position: 0 0;
521
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
522
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
523
+ -webkit-transition: none;
524
+ transition: none;
525
+ }
526
+ .caldera-grid .btn-default:active,
527
+ .caldera-grid .btn-default.active,
528
+ .caldera-grid .open .dropdown-toggle.btn-default {
529
+ border: 1px solid #dcdcdc;
530
+ background-image: -webkit-linear-gradient(top, #f6f6f6 0%, #f1f1f1 100%);
531
+ background-image: linear-gradient(to bottom, #f6f6f6 0%, #f1f1f1 100%);
532
+ background-repeat: repeat-x;
533
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff6f6f6', endColorstr='#fff1f1f1', GradientType=0);
534
+ background-color: #e8e8e8;
535
+ text-shadow: 0 1px 0 #fff;
536
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
537
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
538
+ }
539
+ .caldera-grid .btn-default:focus {
540
+ outline-style: none;
541
+ background-color: #f3f3f3;
542
+ }
543
+ .caldera-grid .btn-default.disabled:hover,
544
+ .caldera-grid .btn-default[disabled]:hover,
545
+ .caldera-grid fieldset[disabled] .btn-default:hover,
546
+ .caldera-grid .btn-default.disabled:focus,
547
+ .caldera-grid .btn-default[disabled]:focus,
548
+ .caldera-grid fieldset[disabled] .btn-default:focus,
549
+ .caldera-grid .btn-default.disabled:active,
550
+ .caldera-grid .btn-default[disabled]:active,
551
+ .caldera-grid fieldset[disabled] .btn-default:active {
552
+ background-color: #f3f3f3;
553
+ text-shadow: none;
554
+ }
555
+ .caldera-grid .btn-default .badge {
556
+ color: #f3f3f3;
557
+ text-shadow: none;
558
+ }
559
  .caldera-grid .btn-primary {
560
+ border: 1px solid #3079ed;
561
  color: #ffffff;
562
+ background-image: -webkit-linear-gradient(top, #4d90fe 0%, #4787ed 100%);
563
+ background-image: linear-gradient(to bottom, #4d90fe 0%, #4787ed 100%);
564
+ background-repeat: repeat-x;
565
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4d90fe', endColorstr='#ff4787ed', GradientType=0);
566
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
567
+ text-shadow: 0 1px rgba(0, 0, 0, 0.1);
568
+ }
569
+ .caldera-grid .btn-primary:hover {
570
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
571
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
572
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
573
  }
574
  .caldera-grid .btn-primary:hover,
575
  .caldera-grid .btn-primary:focus,
576
  .caldera-grid .btn-primary:active,
577
  .caldera-grid .btn-primary.active,
578
+ .caldera-grid .open > .dropdown-toggle.btn-primary {
579
  color: #ffffff;
580
+ border: 1px solid #196aeb;
581
+ background-image: -webkit-linear-gradient(top, #4d90fe 0%, #3078eb 100%);
582
+ background-image: linear-gradient(to bottom, #4d90fe 0%, #3078eb 100%);
583
+ background-repeat: repeat-x;
584
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4d90fe', endColorstr='#ff3078eb', GradientType=0);
585
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
586
+ background-color: #3078eb;
587
  }
588
  .caldera-grid .btn-primary:active,
589
  .caldera-grid .btn-primary.active,
590
+ .caldera-grid .open > .dropdown-toggle.btn-primary {
591
+ border: 1px solid #135fd7;
592
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
593
+ background-image: -webkit-linear-gradient(top, #4d90fe 0%, #1969e8 100%);
594
+ background-image: linear-gradient(to bottom, #4d90fe 0%, #1969e8 100%);
595
+ background-repeat: repeat-x;
596
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4d90fe', endColorstr='#ff1969e8', GradientType=0);
597
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
598
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
599
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
600
+ }
601
+ .caldera-grid .btn-primary:focus {
602
+ border: 1px solid #3079ed;
603
+ -webkit-box-shadow: inset 0 0 0 1px #ffffff;
604
+ box-shadow: inset 0 0 0 1px #ffffff;
605
  }
606
  .caldera-grid .btn-primary.disabled,
607
  .caldera-grid .btn-primary[disabled],
618
  .caldera-grid .btn-primary.disabled.active,
619
  .caldera-grid .btn-primary[disabled].active,
620
  .caldera-grid fieldset[disabled] .btn-primary.active {
621
+ border: 1px solid #3079ed;
622
+ background-image: -webkit-linear-gradient(top, #4d90fe 0%, #4787ed 100%);
623
+ background-image: linear-gradient(to bottom, #4d90fe 0%, #4787ed 100%);
624
+ background-repeat: repeat-x;
625
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4d90fe', endColorstr='#ff4787ed', GradientType=0);
626
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
627
+ background-color: #4d90fe;
628
+ -webkit-box-shadow: none;
629
+ box-shadow: none;
630
  }
631
  .caldera-grid .btn-primary .badge {
632
+ color: #3079ed;
633
  background-color: #ffffff;
634
  }
635
  .caldera-grid .btn-success {
636
+ border: 1px solid #359947;
637
  color: #ffffff;
638
+ background-image: -webkit-linear-gradient(top, #35aa47 0%, #35aa47 100%);
639
+ background-image: linear-gradient(to bottom, #35aa47 0%, #35aa47 100%);
640
+ background-repeat: repeat-x;
641
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff35aa47', endColorstr='#ff35aa47', GradientType=0);
642
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
643
+ text-shadow: 0 1px rgba(0, 0, 0, 0.1);
644
+ }
645
+ .caldera-grid .btn-success:hover {
646
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
647
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
648
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
649
  }
650
  .caldera-grid .btn-success:hover,
651
  .caldera-grid .btn-success:focus,
652
  .caldera-grid .btn-success:active,
653
  .caldera-grid .btn-success.active,
654
+ .caldera-grid .open > .dropdown-toggle.btn-success {
655
  color: #ffffff;
656
+ border: 1px solid #2e863e;
657
+ background-image: -webkit-linear-gradient(top, #35aa47 0%, #2f973f 100%);
658
+ background-image: linear-gradient(to bottom, #35aa47 0%, #2f973f 100%);
659
+ background-repeat: repeat-x;
660
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff35aa47', endColorstr='#ff2f973f', GradientType=0);
661
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
662
+ background-color: #2f973f;
663
  }
664
  .caldera-grid .btn-success:active,
665
  .caldera-grid .btn-success.active,
666
+ .caldera-grid .open > .dropdown-toggle.btn-success {
667
+ border: 1px solid #287335;
668
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
669
+ background-image: -webkit-linear-gradient(top, #35aa47 0%, #298337 100%);
670
+ background-image: linear-gradient(to bottom, #35aa47 0%, #298337 100%);
671
+ background-repeat: repeat-x;
672
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff35aa47', endColorstr='#ff298337', GradientType=0);
673
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
674
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
675
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
676
+ }
677
+ .caldera-grid .btn-success:focus {
678
+ border: 1px solid #359947;
679
+ -webkit-box-shadow: inset 0 0 0 1px #ffffff;
680
+ box-shadow: inset 0 0 0 1px #ffffff;
681
  }
682
  .caldera-grid .btn-success.disabled,
683
  .caldera-grid .btn-success[disabled],
694
  .caldera-grid .btn-success.disabled.active,
695
  .caldera-grid .btn-success[disabled].active,
696
  .caldera-grid fieldset[disabled] .btn-success.active {
697
+ border: 1px solid #359947;
698
+ background-image: -webkit-linear-gradient(top, #35aa47 0%, #35aa47 100%);
699
+ background-image: linear-gradient(to bottom, #35aa47 0%, #35aa47 100%);
700
+ background-repeat: repeat-x;
701
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff35aa47', endColorstr='#ff35aa47', GradientType=0);
702
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
703
+ background-color: #35aa47;
704
+ -webkit-box-shadow: none;
705
+ box-shadow: none;
706
  }
707
  .caldera-grid .btn-success .badge {
708
+ color: #359947;
709
  background-color: #ffffff;
710
  }
711
  .caldera-grid .btn-info {
712
+ border: 1px solid #46b8da;
713
  color: #ffffff;
714
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #5bc0de 100%);
715
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #5bc0de 100%);
716
+ background-repeat: repeat-x;
717
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff5bc0de', GradientType=0);
718
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
719
+ text-shadow: 0 1px rgba(0, 0, 0, 0.1);
720
+ }
721
+ .caldera-grid .btn-info:hover {
722
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
723
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
724
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
725
  }
726
  .caldera-grid .btn-info:hover,
727
  .caldera-grid .btn-info:focus,
728
  .caldera-grid .btn-info:active,
729
  .caldera-grid .btn-info.active,
730
+ .caldera-grid .open > .dropdown-toggle.btn-info {
731
  color: #ffffff;
732
+ border: 1px solid #31b0d5;
733
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #46b8da 100%);
734
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #46b8da 100%);
735
+ background-repeat: repeat-x;
736
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff46b8da', GradientType=0);
737
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
738
+ background-color: #46b8da;
739
  }
740
  .caldera-grid .btn-info:active,
741
  .caldera-grid .btn-info.active,
742
+ .caldera-grid .open > .dropdown-toggle.btn-info {
743
+ border: 1px solid #28a1c5;
744
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
745
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
746
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
747
+ background-repeat: repeat-x;
748
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
749
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
750
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
751
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
752
+ }
753
+ .caldera-grid .btn-info:focus {
754
+ border: 1px solid #46b8da;
755
+ -webkit-box-shadow: inset 0 0 0 1px #ffffff;
756
+ box-shadow: inset 0 0 0 1px #ffffff;
757
  }
758
  .caldera-grid .btn-info.disabled,
759
  .caldera-grid .btn-info[disabled],
770
  .caldera-grid .btn-info.disabled.active,
771
  .caldera-grid .btn-info[disabled].active,
772
  .caldera-grid fieldset[disabled] .btn-info.active {
773
+ border: 1px solid #46b8da;
774
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #5bc0de 100%);
775
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #5bc0de 100%);
776
+ background-repeat: repeat-x;
777
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff5bc0de', GradientType=0);
778
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
779
  background-color: #5bc0de;
780
+ -webkit-box-shadow: none;
781
+ box-shadow: none;
782
  }
783
  .caldera-grid .btn-info .badge {
784
+ color: #46b8da;
785
  background-color: #ffffff;
786
  }
787
  .caldera-grid .btn-warning {
788
+ border: 1px solid #faa328;
789
  color: #ffffff;
790
+ background-image: -webkit-linear-gradient(top, #fbb450 0%, #faa937 100%);
791
+ background-image: linear-gradient(to bottom, #fbb450 0%, #faa937 100%);
792
+ background-repeat: repeat-x;
793
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fffaa937', GradientType=0);
794
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
795
+ text-shadow: 0 1px rgba(0, 0, 0, 0.1);
796
+ }
797
+ .caldera-grid .btn-warning:hover {
798
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
799
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
800
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
801
  }
802
  .caldera-grid .btn-warning:hover,
803
  .caldera-grid .btn-warning:focus,
804
  .caldera-grid .btn-warning:active,
805
  .caldera-grid .btn-warning.active,
806
+ .caldera-grid .open > .dropdown-toggle.btn-warning {
807
  color: #ffffff;
808
+ border: 1px solid #f9980f;
809
+ background-image: -webkit-linear-gradient(top, #fbb450 0%, #f99e1e 100%);
810
+ background-image: linear-gradient(to bottom, #fbb450 0%, #f99e1e 100%);
811
+ background-repeat: repeat-x;
812
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff99e1e', GradientType=0);
813
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
814
+ background-color: #f99e1e;
815
  }
816
  .caldera-grid .btn-warning:active,
817
  .caldera-grid .btn-warning.active,
818
+ .caldera-grid .open > .dropdown-toggle.btn-warning {
819
+ border: 1px solid #e98b06;
820
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
821
+ background-image: -webkit-linear-gradient(top, #fbb450 0%, #f89306 100%);
822
+ background-image: linear-gradient(to bottom, #fbb450 0%, #f89306 100%);
823
+ background-repeat: repeat-x;
824
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89306', GradientType=0);
825
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
826
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
827
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
828
+ }
829
+ .caldera-grid .btn-warning:focus {
830
+ border: 1px solid #faa328;
831
+ -webkit-box-shadow: inset 0 0 0 1px #ffffff;
832
+ box-shadow: inset 0 0 0 1px #ffffff;
833
  }
834
  .caldera-grid .btn-warning.disabled,
835
  .caldera-grid .btn-warning[disabled],
846
  .caldera-grid .btn-warning.disabled.active,
847
  .caldera-grid .btn-warning[disabled].active,
848
  .caldera-grid fieldset[disabled] .btn-warning.active {
849
+ border: 1px solid #faa328;
850
+ background-image: -webkit-linear-gradient(top, #fbb450 0%, #faa937 100%);
851
+ background-image: linear-gradient(to bottom, #fbb450 0%, #faa937 100%);
852
+ background-repeat: repeat-x;
853
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fffaa937', GradientType=0);
854
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
855
+ background-color: #fbb450;
856
+ -webkit-box-shadow: none;
857
+ box-shadow: none;
858
  }
859
  .caldera-grid .btn-warning .badge {
860
+ color: #faa328;
861
  background-color: #ffffff;
862
  }
863
  .caldera-grid .btn-danger {
864
+ border: 1px solid #c6322a;
865
  color: #ffffff;
866
+ background-image: -webkit-linear-gradient(top, #dd4b39 0%, #d14836 100%);
867
+ background-image: linear-gradient(to bottom, #dd4b39 0%, #d14836 100%);
868
+ background-repeat: repeat-x;
869
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdd4b39', endColorstr='#ffd14836', GradientType=0);
870
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
871
+ text-shadow: 0 1px rgba(0, 0, 0, 0.1);
872
+ }
873
+ .caldera-grid .btn-danger:hover {
874
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
875
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
876
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
877
  }
878
  .caldera-grid .btn-danger:hover,
879
  .caldera-grid .btn-danger:focus,
880
  .caldera-grid .btn-danger:active,
881
  .caldera-grid .btn-danger.active,
882
+ .caldera-grid .open > .dropdown-toggle.btn-danger {
883
  color: #ffffff;
884
+ border: 1px solid #b12d26;
885
+ background-image: -webkit-linear-gradient(top, #dd4b39 0%, #c13e2c 100%);
886
+ background-image: linear-gradient(to bottom, #dd4b39 0%, #c13e2c 100%);
887
+ background-repeat: repeat-x;
888
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdd4b39', endColorstr='#ffc13e2c', GradientType=0);
889
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
890
+ background-color: #c13e2c;
891
  }
892
  .caldera-grid .btn-danger:active,
893
  .caldera-grid .btn-danger.active,
894
+ .caldera-grid .open > .dropdown-toggle.btn-danger {
895
+ border: 1px solid #9c2721;
896
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
897
+ background-image: -webkit-linear-gradient(top, #dd4b39 0%, #ad3727 100%);
898
+ background-image: linear-gradient(to bottom, #dd4b39 0%, #ad3727 100%);
899
+ background-repeat: repeat-x;
900
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdd4b39', endColorstr='#ffad3727', GradientType=0);
901
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
902
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
903
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
904
+ }
905
+ .caldera-grid .btn-danger:focus {
906
+ border: 1px solid #c6322a;
907
+ -webkit-box-shadow: inset 0 0 0 1px #ffffff;
908
+ box-shadow: inset 0 0 0 1px #ffffff;
909
  }
910
  .caldera-grid .btn-danger.disabled,
911
  .caldera-grid .btn-danger[disabled],
922
  .caldera-grid .btn-danger.disabled.active,
923
  .caldera-grid .btn-danger[disabled].active,
924
  .caldera-grid fieldset[disabled] .btn-danger.active {
925
+ border: 1px solid #c6322a;
926
+ background-image: -webkit-linear-gradient(top, #dd4b39 0%, #d14836 100%);
927
+ background-image: linear-gradient(to bottom, #dd4b39 0%, #d14836 100%);
928
+ background-repeat: repeat-x;
929
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdd4b39', endColorstr='#ffd14836', GradientType=0);
930
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
931
+ background-color: #dd4b39;
932
+ -webkit-box-shadow: none;
933
+ box-shadow: none;
934
  }
935
  .caldera-grid .btn-danger .badge {
936
+ color: #c6322a;
937
  background-color: #ffffff;
938
  }
939
  .caldera-grid .btn-link {
940
+ color: #1155cc;
 
 
 
941
  }
942
  .caldera-grid .btn-link,
943
  .caldera-grid .btn-link:active,
955
  }
956
  .caldera-grid .btn-link:hover,
957
  .caldera-grid .btn-link:focus {
958
+ color: #1155cc;
 
959
  background-color: transparent;
960
+ -webkit-box-shadow: none;
961
+ box-shadow: none;
962
  }
963
  .caldera-grid .btn-link[disabled]:hover,
964
  .caldera-grid fieldset[disabled] .btn-link:hover,
965
  .caldera-grid .btn-link[disabled]:focus,
966
  .caldera-grid fieldset[disabled] .btn-link:focus {
967
+ color: #333333;
 
968
  }
969
+ .caldera-grid .btn-lg,
970
+ .caldera-grid .btn-group-lg > .btn {
971
+ padding: 9px 14px;
972
+ font-size: 14px;
973
+ line-height: 1.3;
974
+ border-radius: 2px;
975
  }
976
+ .caldera-grid .btn-sm,
977
+ .caldera-grid .btn-group-sm > .btn {
978
+ padding: 3px 8px;
979
  font-size: 12px;
980
  line-height: 1.5;
981
+ border-radius: 2px;
982
  }
983
+ .caldera-grid .btn-xs,
984
+ .caldera-grid .btn-group-xs > .btn {
985
+ padding: 2px 6px;
986
+ font-size: 11px;
987
+ line-height: 1.25;
988
+ border-radius: 1px;
989
  }
990
  .caldera-grid .btn-block {
991
  display: block;
1001
  .caldera-grid input[type="button"].btn-block {
1002
  width: 100%;
1003
  }
1004
+ .caldera-grid .btn-toolbar > .btn,
1005
+ .caldera-grid .btn-toolbar > .btn-group,
1006
+ .caldera-grid .btn-toolbar > .input-group {
1007
+ margin-left: 16px;
 
 
1008
  }
1009
+ .caldera-grid .btn-group > .btn + .dropdown-toggle {
1010
+ -webkit-box-shadow: none;
1011
+ box-shadow: none;
1012
  }
1013
+ .caldera-grid .btn-group > .dropdown-toggle:hover {
1014
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
1015
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
1016
+ }
1017
+ .caldera-grid .btn-group > .btn-primary.dropdown-toggle:hover,
1018
+ .caldera-grid .btn-group > .btn-info.dropdown-toggle:hover,
1019
+ .caldera-grid .btn-group > .btn-warning.dropdown-toggle:hover,
1020
+ .caldera-grid .btn-group > .btn-danger.dropdown-toggle:hover,
1021
+ .caldera-grid .btn-group > .btn-success.dropdown-toggle:hover {
1022
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
1023
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
1024
+ }
1025
+ .caldera-grid .btn-group > .btn.dropdown-toggle:active,
1026
+ .caldera-grid .btn-group > .btn.dropdown-toggle.active {
1027
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
1028
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
1029
+ }
1030
+ .caldera-grid .btn-group > .btn-primary.dropdown-toggle:active,
1031
+ .caldera-grid .btn-group > .btn-primary.dropdown-toggle.active,
1032
+ .caldera-grid .btn-group > .btn-warning.dropdown-toggle:active,
1033
+ .caldera-grid .btn-group > .btn-warning.dropdown-toggle.active,
1034
+ .caldera-grid .btn-group > .btn-danger.dropdown-toggle:active,
1035
+ .caldera-grid .btn-group > .btn-danger.dropdown-toggle.active,
1036
+ .caldera-grid .btn-group > .btn-success.dropdown-toggle:active,
1037
+ .caldera-grid .btn-group > .btn-success.dropdown-toggle.active,
1038
+ .caldera-grid .btn-group > .btn-info.dropdown-toggle:active,
1039
+ .caldera-grid .btn-group > .btn-info.dropdown-toggle.active {
1040
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1041
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1042
+ }
1043
+ .caldera-grid .btn-group > .btn-sm.dropdown-toggle {
1044
+ padding: 5px 7px;
1045
+ }
1046
+ .caldera-grid .btn-group > .btn-lg.dropdown-toggle {
1047
+ padding: 9px 9px;
1048
+ }
1049
+ .caldera-grid .btn-group.open .dropdown-toggle {
1050
+ -webkit-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15);
1051
+ box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15);
1052
+ }
1053
+ .caldera-grid .btn-group.open .btn.dropdown-toggle {
1054
+ background-color: #f3f3f3;
1055
+ background-image: none;
1056
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
1057
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
1058
  }
1059
+ .caldera-grid .btn-group.open .btn-primary.dropdown-toggle {
1060
+ background-color: #4d90fe;
1061
+ background-image: none;
1062
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1063
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1064
  }
1065
+ .caldera-grid .btn-group.open .btn-warning.dropdown-toggle {
1066
+ background-color: #faa937;
1067
+ background-image: none;
1068
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1069
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1070
  }
1071
+ .caldera-grid .btn-group.open .btn-danger.dropdown-toggle {
1072
+ background-color: #d84a38;
1073
+ background-image: none;
1074
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1075
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1076
  }
1077
+ .caldera-grid .btn-group.open .btn-success.dropdown-toggle {
1078
+ background-color: #35aa47;
1079
+ background-image: none;
1080
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1081
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1082
  }
1083
+ .caldera-grid .btn-group.open .btn-info.dropdown-toggle {
1084
+ background-color: #5bc0de;
1085
+ background-image: none;
1086
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1087
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
1088
  }
1089
+ .caldera-grid .btn-lg .caret {
1090
+ border-width: 5px 5px 0;
1091
+ }
1092
+ .caldera-grid .dropup .btn-lg .caret {
1093
+ border-width: 0 5px 5px;
1094
+ }
1095
+ .caldera-grid .btn-group-vertical > .btn:first-child:not(:last-child) {
1096
+ border-top-right-radius: 2px;
1097
+ }
1098
+ .caldera-grid .btn-group-vertical > .btn:last-child:not(:first-child) {
1099
+ border-bottom-left-radius: 2px;
1100
+ }
1101
+ .caldera-grid .input-group-lg > .form-control,
1102
+ .caldera-grid .input-group-lg > .input-group-addon,
1103
+ .caldera-grid .input-group-lg > .input-group-btn > .btn {
1104
+ height: 38px;
1105
+ padding: 9px 14px;
1106
+ font-size: 14px;
1107
+ line-height: 1.3;
1108
+ border-radius: 1px;
1109
+ }
1110
+ .caldera-grid select.input-group-lg > .form-control,
1111
+ .caldera-grid select.input-group-lg > .input-group-addon,
1112
+ .caldera-grid select.input-group-lg > .input-group-btn > .btn {
1113
+ height: 38px;
1114
+ line-height: 38px;
1115
+ }
1116
+ .caldera-grid textarea.input-group-lg > .form-control,
1117
+ .caldera-grid textarea.input-group-lg > .input-group-addon,
1118
+ .caldera-grid textarea.input-group-lg > .input-group-btn > .btn,
1119
+ .caldera-grid select[multiple].input-group-lg > .form-control,
1120
+ .caldera-grid select[multiple].input-group-lg > .input-group-addon,
1121
+ .caldera-grid select[multiple].input-group-lg > .input-group-btn > .btn {
1122
+ height: auto;
1123
+ }
1124
+ .caldera-grid .input-group-sm > .form-control,
1125
+ .caldera-grid .input-group-sm > .input-group-addon,
1126
+ .caldera-grid .input-group-sm > .input-group-btn > .btn {
1127
+ height: 26px;
1128
+ padding: 3px 8px;
1129
+ font-size: 12px;
1130
+ line-height: 1.5;
1131
+ border-radius: 1px;
1132
+ }
1133
+ .caldera-grid select.input-group-sm > .form-control,
1134
+ .caldera-grid select.input-group-sm > .input-group-addon,
1135
+ .caldera-grid select.input-group-sm > .input-group-btn > .btn {
1136
+ height: 26px;
1137
+ line-height: 26px;
1138
+ }
1139
+ .caldera-grid textarea.input-group-sm > .form-control,
1140
+ .caldera-grid textarea.input-group-sm > .input-group-addon,
1141
+ .caldera-grid textarea.input-group-sm > .input-group-btn > .btn,
1142
+ .caldera-grid select[multiple].input-group-sm > .form-control,
1143
+ .caldera-grid select[multiple].input-group-sm > .input-group-addon,
1144
+ .caldera-grid select[multiple].input-group-sm > .input-group-btn > .btn {
1145
+ height: auto;
1146
+ }
1147
+ .caldera-grid .input-group-addon,
1148
+ .caldera-grid .input-group-btn,
1149
+ .caldera-grid .input-group .form-control {
1150
+ margin: 0;
1151
+ border-radius: 0;
1152
+ }
1153
+ .caldera-grid .input-group-addon {
1154
+ padding: 5px 8px;
1155
+ font-size: 13px;
1156
+ color: #555555;
1157
+ border: 1px solid #d9d9d9;
1158
+ border-top-color: #c0c0c0;
1159
+ border-radius: 2px;
1160
+ }
1161
+ .caldera-grid .input-group-addon.input-sm {
1162
+ padding: 3px 8px;
1163
+ font-size: 12px;
1164
+ border-radius: 1px;
1165
+ }
1166
+ .caldera-grid .input-group-addon.input-lg {
1167
+ padding: 9px 14px;
1168
+ font-size: 14px;
1169
+ border-radius: 1px;
1170
+ }
1171
+ .caldera-grid .input-group-addon input[type="radio"],
1172
+ .caldera-grid .input-group-addon input[type="checkbox"] {
1173
+ margin-bottom: -3px;
1174
+ }
1175
+
1176
+
1177
+ .caldera-grid .breadcrumb {
1178
+ padding: 6px 12px;
1179
+ margin-bottom: 20px;
1180
+ list-style: none;
1181
+ background-color: #f5f5f5;
1182
+ border-radius: 4px;
1183
+ }
1184
+ .caldera-grid .breadcrumb > li {
1185
+ display: inline-block;
1186
+ margin: 0;
1187
  }
1188
+ .caldera-grid .breadcrumb > li + li:before {
1189
+ content: "/\00a0";
1190
+ padding: 0 5px;
1191
+ color: #cccccc;
1192
  }
1193
+ .caldera-grid .breadcrumb > .active,
1194
+ .caldera-grid .breadcrumb > .active > a {
1195
+ color: #777777;
1196
  }
1197
+ .breadcrumb > li.active.error > a,
1198
+ .breadcrumb > li.error > a {
1199
+ color: #ff0000;
1200
+ }
assets/css/caldera-grid.css CHANGED
@@ -203,7 +203,6 @@
203
  line-height: inherit;
204
  }
205
  .caldera-grid a {
206
- color: #428bca;
207
  text-decoration: none;
208
  }
209
  .caldera-grid a:hover,
@@ -500,7 +499,6 @@
500
  line-height: inherit;
501
  }
502
  .caldera-grid a {
503
- color: #428bca;
504
  text-decoration: none;
505
  }
506
  .caldera-grid a:hover,
203
  line-height: inherit;
204
  }
205
  .caldera-grid a {
 
206
  text-decoration: none;
207
  }
208
  .caldera-grid a:hover,
499
  line-height: inherit;
500
  }
501
  .caldera-grid a {
 
502
  text-decoration: none;
503
  }
504
  .caldera-grid a:hover,
assets/css/editor-grid.css CHANGED
@@ -347,7 +347,13 @@
347
  .template-element.ui-draggable-dragging{
348
  z-index: 1000;
349
  }
350
-
 
 
 
 
 
 
351
 
352
  .layout-grid article,.layout-grid aside,.layout-grid details,.layout-grid figcaption,.layout-grid figure,.layout-grid footer,.layout-grid header,.layout-grid hgroup,.layout-grid main,.layout-grid nav,.layout-grid section,.layout-grid summary{display:block;}
353
  .layout-grid audio,.layout-grid canvas,.layout-grid video{display:inline-block;}
347
  .template-element.ui-draggable-dragging{
348
  z-index: 1000;
349
  }
350
+ .layout-form-field.ui-sortable-placeholder {
351
+ background-color: #f8f8f8;
352
+ border-bottom: 1px dashed #dedede;
353
+ border-top: 1px dashed #dedede;
354
+ visibility: visible !important;
355
+ }
356
+ .ui-sortable-helper{overflow: hidden;}
357
 
358
  .layout-grid article,.layout-grid aside,.layout-grid details,.layout-grid figcaption,.layout-grid figure,.layout-grid footer,.layout-grid header,.layout-grid hgroup,.layout-grid main,.layout-grid nav,.layout-grid section,.layout-grid summary{display:block;}
359
  .layout-grid audio,.layout-grid canvas,.layout-grid video{display:inline-block;}
assets/css/modals.css CHANGED
@@ -56,8 +56,14 @@
56
  right: 0;
57
  top: 43px;
58
  }
 
 
 
 
 
 
59
  .caldera-modal-body .form-panel {
60
- bottom: -30px;
61
  left: 12px;
62
  overflow: auto;
63
  position: absolute;
@@ -121,7 +127,7 @@
121
  /** DETAIL PROFILE MODAL */
122
  .modal-inside {
123
  height: 100%;
124
- margin-left: 170px;
125
  padding-right: 10px;
126
  overflow: auto;
127
  }
56
  right: 0;
57
  top: 43px;
58
  }
59
+ .caldera-modal-body .import-warning{
60
+ margin: 0;
61
+ padding: 4px 0;
62
+ color: #ff1111;
63
+ }
64
+
65
  .caldera-modal-body .form-panel {
66
+ bottom: 0;
67
  left: 12px;
68
  overflow: auto;
69
  position: absolute;
127
  /** DETAIL PROFILE MODAL */
128
  .modal-inside {
129
  height: 100%;
130
+ margin-left: 158px;
131
  padding-right: 10px;
132
  overflow: auto;
133
  }
assets/css/processors-edit.css CHANGED
@@ -19,6 +19,9 @@
19
  }
20
  .caldera-editor-processor-config {
21
  float: left;
 
 
 
22
  width: 500px;
23
  }
24
  h3.caldera-editor-processor-title {
19
  }
20
  .caldera-editor-processor-config {
21
  float: left;
22
+ width: auto;
23
+ }
24
+ .caldera-editor-processor-config-wrapper {
25
  width: 500px;
26
  }
27
  h3.caldera-editor-processor-title {
assets/images/checkmark.png ADDED
Binary file
assets/js/conditionals.js CHANGED
@@ -1,9 +1,30 @@
1
  (function($){
2
 
3
- function calders_forms_check_conditions(el){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  for(var field in caldera_conditionals){
6
-
7
  // each conditional
8
  var fieldwrapper = $('#conditional_' + field);
9
 
@@ -11,81 +32,103 @@
11
  continue;
12
  }
13
  var type = caldera_conditionals[field].type,
14
- groups = caldera_conditionals[field].group,
15
- trues = [];
16
 
17
  // has a wrapper - bind conditions
18
  for(var id in groups){
19
 
20
- var truelines = [],
21
- lines = groups[id];
22
  // go over each line in a group to find a false
23
- for(var lid in lines){
24
  /// get field
25
- var comparefield = $('[data-field="' + lines[lid].field + '"]'),
26
- linetmp = false;
27
- if( comparefield.is(':radio,:checkbox')){
28
- comparefield = comparefield.filter(':checked');
 
 
 
 
 
 
29
  }
30
-
31
- for( var i = 0; i<comparefield.length; i++){
32
-
33
- switch(lines[lid].compare) {
34
- case 'is':
35
- if(comparefield[i].value.toLowerCase() === lines[lid].value.toLowerCase()){
36
- linetmp = true;
37
- }
38
- break;
39
- case 'isnot':
40
- if(comparefield[i].value.toLowerCase() !== lines[lid].value.toLowerCase()){
41
- linetmp = true;
42
- }
43
- break;
44
- case '>':
45
- if( parseFloat( comparefield[i].value ) > parseFloat( lines[lid].value ) ){
46
- linetmp = true;
47
- }
48
- break;
49
- case '<':
50
- if( parseFloat( comparefield[i].value ) < parseFloat( lines[lid].value ) ){
51
- linetmp = true;
52
- }
53
- break;
54
- case 'startswith':
55
- if( comparefield[i].value.toLowerCase().substr(0, lines[lid].value.toLowerCase().length ) === lines[lid].value.toLowerCase()){
56
- linetmp = true;
57
- }
58
- break;
59
- case 'endswith':
60
- if( comparefield[i].value.toLowerCase().substr(comparefield[i].value.toLowerCase().length - lines[lid].value.toLowerCase().length ) === lines[lid].value.toLowerCase()){
61
- linetmp = true;
62
- }
63
- break;
64
- case 'contains':
65
- if( comparefield[i].value.toLowerCase().indexOf( lines[lid].value ) >= 0 ){
66
- linetmp = true;
67
- }
68
- break;
69
  }
70
  }
71
 
72
- truelines.push(linetmp);
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  // add result in
75
- if(truelines.length && truelines.indexOf(false) < 0){
76
- trues.push(true);
77
- }else{
78
- trues.push(false);
 
 
79
  }
 
80
 
81
  }
82
 
83
- console.log(trues);
84
 
85
  var template = $('#conditional-' + field + '-tmpl').html(),
86
- target = $('#conditional_' + field),
87
- action;
88
-
 
89
  if(trues.length && trues.indexOf(true) >= 0){
90
  if(type === 'show'){
91
  action = 'show';
@@ -103,24 +146,25 @@
103
  if(action === 'show'){
104
  // show - get template and place it in.
105
  if(!target.html().length){
106
- target.html(template);
107
- }
108
  }else if (action === 'hide'){
109
- target.empty();
 
 
 
110
  }
111
 
112
  }
113
  }
114
 
115
  if(typeof caldera_conditionals !== 'undefined'){
116
-
117
- $('.caldera_forms_form').on('change keyup', 'input,select,textarea', function(e){
118
-
119
  calders_forms_check_conditions();
120
 
121
  });
122
  // init
123
  calders_forms_check_conditions();
124
  }
125
-
126
  })(jQuery);
1
  (function($){
2
 
3
+ // IE8 compatibility
4
+ if (!Array.prototype.indexOf){
5
+ Array.prototype.indexOf = function(elt /*, from*/){
6
+ var len = this.length >>> 0;
7
+
8
+ var from = Number(arguments[1]) || 0;
9
+ from = (from < 0)
10
+ ? Math.ceil(from)
11
+ : Math.floor(from);
12
+ if (from < 0)
13
+ from += len;
14
+
15
+ for (; from < len; from++){
16
+ if (from in this &&
17
+ this[from] === elt)
18
+ return from;
19
+ }
20
+ return -1;
21
+ };
22
+ }
23
+
24
+ function calders_forms_check_conditions(){
25
 
26
  for(var field in caldera_conditionals){
27
+
28
  // each conditional
29
  var fieldwrapper = $('#conditional_' + field);
30
 
32
  continue;
33
  }
34
  var type = caldera_conditionals[field].type,
35
+ groups = caldera_conditionals[field].group,
36
+ trues = [];
37
 
38
  // has a wrapper - bind conditions
39
  for(var id in groups){
40
 
41
+ var truelines = {},
42
+ lines = groups[id];
43
  // go over each line in a group to find a false
44
+ for(var lid in lines){
45
  /// get field
46
+ var compareelement = $('[data-field="' + lines[lid].field + '"]'),
47
+ comparefield = [],
48
+ comparevalue = (typeof lines[lid].value === 'function' ? lines[lid].value() : lines[lid].value);
49
+
50
+ truelines[lid] = false;
51
+
52
+ if( compareelement.is(':radio,:checkbox')){
53
+ compareelement = compareelement.filter(':checked');
54
+ }else if( compareelement.is('div')){
55
+ compareelement = $('<input>').val( compareelement.html() );
56
  }
57
+ if(!compareelement.length){
58
+ comparefield.push(lines[lid].field);
59
+ }else{
60
+ for( var i = 0; i<compareelement.length; i++){
61
+ comparefield.push(compareelement[i].value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
63
  }
64
 
65
+ switch(lines[lid].compare) {
66
+ case 'is':
67
+ if(comparefield.length){
68
+ if(comparefield.indexOf(comparevalue) >= 0){
69
+ truelines[lid] = true;
70
+ }
71
+ }
72
+ break;
73
+ case 'isnot':
74
+ if(comparefield.length){
75
+ if(comparefield.indexOf(comparevalue) < 0){
76
+ truelines[lid] = true;
77
+ }
78
+ }
79
+ break;
80
+ case '>':
81
+ if( parseFloat( comparefield.reduce(function(a, b) {return a + b;}) ) > parseFloat( comparevalue ) ){
82
+ truelines[lid] = true;
83
+ }
84
+ break;
85
+ case '<':
86
+ if( parseFloat( comparefield.reduce(function(a, b) {return a + b;}) ) < parseFloat( comparevalue ) ){
87
+ truelines[lid] = true;
88
+ }
89
+ break;
90
+ case 'startswith':
91
+ for( var i = 0; i<comparefield.length; i++){
92
+ if( comparefield[i].toLowerCase().substr(0, comparevalue.toLowerCase().length ) === comparevalue.toLowerCase()){
93
+ truelines[lid] = true;
94
+ }
95
+ }
96
+ break;
97
+ case 'endswith':
98
+ for( var i = 0; i<comparefield.length; i++){
99
+ if( comparefield[i].toLowerCase().substr(comparefield[i].toLowerCase().length - comparevalue.toLowerCase().length ) === comparevalue.toLowerCase()){
100
+ truelines[lid] = true;
101
+ }
102
+ }
103
+ break;
104
+ case 'contains':
105
+ for( var i = 0; i<comparefield.length; i++){
106
+ if( comparefield[i].toLowerCase().indexOf( comparevalue ) >= 0 ){
107
+ truelines[lid] = true;
108
+ }
109
+ }
110
+ break;
111
+ }
112
+ }
113
  // add result in
114
+ istrue = true;
115
+ for( var prop in truelines ){
116
+ if(truelines[prop] === false){
117
+ istrue = false;
118
+ break;
119
+ }
120
  }
121
+ trues.push(istrue);
122
 
123
  }
124
 
125
+
126
 
127
  var template = $('#conditional-' + field + '-tmpl').html(),
128
+ target = $('#conditional_' + field),
129
+ target_field= $('[data-field="' + field + '"]'),
130
+ action;
131
+
132
  if(trues.length && trues.indexOf(true) >= 0){
133
  if(type === 'show'){
134
  action = 'show';
146
  if(action === 'show'){
147
  // show - get template and place it in.
148
  if(!target.html().length){
149
+ target.html(template).trigger('cf.add');
150
+ }
151
  }else if (action === 'hide'){
152
+ if(target.html().length){
153
+ target_field.val('').empty().prop('checked', false);
154
+ target.empty().trigger('cf.remove');
155
+ }
156
  }
157
 
158
  }
159
  }
160
 
161
  if(typeof caldera_conditionals !== 'undefined'){
162
+
163
+ $('.caldera_forms_form').on('change keyup', '[data-field]', function(e){
 
164
  calders_forms_check_conditions();
165
 
166
  });
167
  // init
168
  calders_forms_check_conditions();
169
  }
 
170
  })(jQuery);
assets/js/edit.js CHANGED
@@ -47,10 +47,66 @@ function build_conditions_config(obj){
47
  jQuery(function($){
48
 
49
 
50
- $('.edit-update-trigger').baldrick({
51
- method : 'POST'
52
- });
 
 
 
 
 
 
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  /*
56
  * Build the fieltypes config
@@ -58,7 +114,7 @@ jQuery(function($){
58
  *
59
  */
60
  function build_fieldtype_config(el){
61
-
62
  var select = $(el),
63
  templ = $('#' + select.val() + '_tmpl').length ? $('#' + select.val() + '_tmpl').html() : $('#noconfig_field_templ').html(),
64
  parent = select.closest('.caldera-editor-field-config-wrapper'),
@@ -123,9 +179,14 @@ jQuery(function($){
123
 
124
  baldrickTriggers();
125
 
 
 
 
 
126
  }
127
 
128
  function build_field_preview(id){
 
129
  var panel = $('#' + id),
130
  select = panel.find('.caldera-select-field-type'),
131
  preview_parent = $('.layout-form-field[data-config="' + id + '"]'),
@@ -141,11 +202,10 @@ jQuery(function($){
141
  basename = field.prop('name').split('[' + id + ']')[1].substr(1),
142
  name = basename.substr(0, basename.length-1).split(']['),
143
  value = ( field.is(':checkbox,:radio') ? field.filter(':checked').val() : field.val() ),
144
- lineconf = {};
145
-
146
-
147
-
148
  for(var i = name.length-1; i >= 0; i--){
 
149
  if(i === name.length-1){
150
  lineconf[name[i]] = value;
151
  }else{
@@ -156,8 +216,7 @@ jQuery(function($){
156
  }
157
  $.extend(true, config, lineconf);
158
  });
159
-
160
-
161
  preview_target.html( template(config) );
162
  preview_parent.removeClass('button');
163
 
@@ -352,6 +411,7 @@ jQuery(function($){
352
  clicked.addClass('field-edit-open');
353
  }
354
 
 
355
  });
356
  $('.caldera-editor-body').on('keydown', '.field-config', function(e){
357
  if($(this).is('textarea')){
@@ -490,11 +550,9 @@ jQuery(function($){
490
  // remove line
491
  line.remove();
492
  rebuild_field_binding();
 
493
  });
494
 
495
-
496
-
497
-
498
  });
499
 
500
 
@@ -694,7 +752,7 @@ jQuery(function($){
694
 
695
  var field = $(this),
696
  type = field.data('condition'),
697
- field_id = this.value,
698
  pid = field.data('id'),
699
  field_wrapper = $('#' + field_id),
700
  options_wrap = field_wrapper.find('.caldera-config-group-toggle-options'),
@@ -709,20 +767,22 @@ jQuery(function($){
709
  if(curval.length){
710
  if(curval.val().length){
711
  target.data('value', curval.val());
 
712
  }
713
  }
714
 
715
  if(options_wrap.length){
716
  var options_rows = options_wrap.find('.toggle_option_row'),
717
  out = '<select name="' + name + '[value]" class="caldera-processor-value-bind caldera-conditional-value-field" data-field="' + field_id + '" style="max-width: 170px; width: 170px;">';
718
-
719
  options_rows.each(function(k,v){
720
  var value = $(v).find('.toggle_value_field').val(),
721
  label = $(v).find('.toggle_label_field').val(),
722
  sel = '';
723
 
724
  if(target.data('value')){
725
- if(target.data('value') === value){
 
726
  sel = ' selected="selected"';
727
  }
728
  }
@@ -774,14 +834,26 @@ jQuery(function($){
774
  // load fist group
775
  $('.caldera-group-nav').first().find('a').trigger('click');
776
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
777
 
778
- });//
779
-
780
-
781
-
782
-
783
-
784
-
785
-
786
 
 
 
787
 
47
  jQuery(function($){
48
 
49
 
50
+ $('.caldera-header-save-button').baldrick({
51
+ method : 'POST',
52
+ request : 'admin.php?page=caldera-forms',
53
+ before : function(el, e){
54
+ e.preventDefault();
55
+ $('#save_indicator').addClass('loading');
56
+ if(tinyMCE){
57
+ tinyMCE.triggerSave();
58
+ }
59
 
60
+ var config = {},
61
+ data_fields = $('.caldera-forms-options-form').find('input,radio,checkbox,select,textarea'),
62
+ objects = [],
63
+ arraynames = {};
64
+
65
+ //data_fields.each(function(k,v){
66
+ for( var v = 0; v < data_fields.length; v++){
67
+ if( data_fields[v].getAttribute('name') === null){
68
+ continue;
69
+ }
70
+ var field = $(data_fields[v]),
71
+ basename = field.prop('name').replace(/\[/gi,':').replace(/\]/gi,''),//.split('[' + id + ']')[1].substr(1),
72
+ name = basename.split(':'),
73
+ value = ( field.is(':checkbox,:radio') ? field.filter(':checked').val() : field.val() ),
74
+ lineconf = {};
75
+
76
+ for(var i = name.length-1; i >= 0; i--){
77
+ var nestname = name[i];
78
+ if(nestname.length === 0){
79
+ if( typeof arraynames[name[i-1]] === 'undefined'){
80
+ arraynames[name[i-1]] = 0;
81
+ }else{
82
+ arraynames[name[i-1]] += 1;
83
+ }
84
+ nestname = arraynames[name[i-1]];
85
+ }
86
+ if(i === name.length-1){
87
+ lineconf[nestname] = value;
88
+ }else{
89
+ var newobj = lineconf;
90
+ lineconf = {};
91
+ lineconf[nestname] = newobj;
92
+ }
93
+ }
94
+
95
+ $.extend(true, config, lineconf);
96
+ };
97
+
98
+ $(el).data('cf_edit_nonce', config.cf_edit_nonce);
99
+ $(el).data('_wp_http_referer', config._wp_http_referer);
100
+ $(el).data('sender', 'ajax');
101
+ $(el).data('config', JSON.stringify(config.config));
102
+
103
+ return true;
104
+ },
105
+ complete: function(){
106
+
107
+ $('.wrapper-instance-pane .field-config').prop('disabled', false);
108
+ }
109
+ });
110
 
111
  /*
112
  * Build the fieltypes config
114
  *
115
  */
116
  function build_fieldtype_config(el){
117
+
118
  var select = $(el),
119
  templ = $('#' + select.val() + '_tmpl').length ? $('#' + select.val() + '_tmpl').html() : $('#noconfig_field_templ').html(),
120
  parent = select.closest('.caldera-editor-field-config-wrapper'),
179
 
180
  baldrickTriggers();
181
 
182
+ // seup options
183
+ parent.find('.toggle_show_values').trigger('change');
184
+
185
+
186
  }
187
 
188
  function build_field_preview(id){
189
+
190
  var panel = $('#' + id),
191
  select = panel.find('.caldera-select-field-type'),
192
  preview_parent = $('.layout-form-field[data-config="' + id + '"]'),
202
  basename = field.prop('name').split('[' + id + ']')[1].substr(1),
203
  name = basename.substr(0, basename.length-1).split(']['),
204
  value = ( field.is(':checkbox,:radio') ? field.filter(':checked').val() : field.val() ),
205
+ lineconf = {};
206
+
 
 
207
  for(var i = name.length-1; i >= 0; i--){
208
+
209
  if(i === name.length-1){
210
  lineconf[name[i]] = value;
211
  }else{
216
  }
217
  $.extend(true, config, lineconf);
218
  });
219
+
 
220
  preview_target.html( template(config) );
221
  preview_parent.removeClass('button');
222
 
411
  clicked.addClass('field-edit-open');
412
  }
413
 
414
+
415
  });
416
  $('.caldera-editor-body').on('keydown', '.field-config', function(e){
417
  if($(this).is('textarea')){
550
  // remove line
551
  line.remove();
552
  rebuild_field_binding();
553
+ $(document).trigger('field.removed');
554
  });
555
 
 
 
 
556
  });
557
 
558
 
752
 
753
  var field = $(this),
754
  type = field.data('condition'),
755
+ field_id = this.value.replace('{','_').replace('}','_'),
756
  pid = field.data('id'),
757
  field_wrapper = $('#' + field_id),
758
  options_wrap = field_wrapper.find('.caldera-config-group-toggle-options'),
767
  if(curval.length){
768
  if(curval.val().length){
769
  target.data('value', curval.val());
770
+ console.log(curval.val());
771
  }
772
  }
773
 
774
  if(options_wrap.length){
775
  var options_rows = options_wrap.find('.toggle_option_row'),
776
  out = '<select name="' + name + '[value]" class="caldera-processor-value-bind caldera-conditional-value-field" data-field="' + field_id + '" style="max-width: 170px; width: 170px;">';
777
+ out += '<option value=""></option>';
778
  options_rows.each(function(k,v){
779
  var value = $(v).find('.toggle_value_field').val(),
780
  label = $(v).find('.toggle_label_field').val(),
781
  sel = '';
782
 
783
  if(target.data('value')){
784
+ if(target.data('value').toString() === value){
785
+ console.log('YES');
786
  sel = ' selected="selected"';
787
  }
788
  }
834
  // load fist group
835
  $('.caldera-group-nav').first().find('a').trigger('click');
836
 
837
+ // toggle set values
838
+ $('.caldera-editor-body').on('change', '.toggle_show_values', function(e){
839
+ var clicked = $(this),
840
+ wrap = clicked.closest('.caldera-config-group-toggle-options');
841
+ values = wrap.find('.toggle_value_field'),
842
+ lables = wrap.find('.toggle_label_field'),
843
+ field_lables = wrap.find('.caldera-config-group-option-labels');
844
+
845
+ if(!clicked.prop('checked')){
846
+ values.prop('disabled', true).hide();
847
+ lables.css('width', 245);
848
+ field_lables.hide();
849
+ }else{
850
+ values.prop('disabled', false).show();
851
+ lables.css('width', '');
852
+ field_lables.show();
853
+ }
854
 
855
+ lables.trigger('toggle.values');
 
 
 
 
 
 
 
856
 
857
+ });
858
+ });//
859
 
assets/js/frontend-script-init.js CHANGED
@@ -1,8 +1,6 @@
1
  (function($){
2
-
3
  $('document').ready(function(){
4
  // check for init function
5
-
6
  $('.init_field_type[data-type]').each(function(k,v){
7
  var ftype = $(v);
8
  if( typeof window[ftype.data('type') + '_init'] === 'function' ){
@@ -11,4 +9,75 @@
11
  });
12
  });
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  })(jQuery);
1
  (function($){
 
2
  $('document').ready(function(){
3
  // check for init function
 
4
  $('.init_field_type[data-type]').each(function(k,v){
5
  var ftype = $(v);
6
  if( typeof window[ftype.data('type') + '_init'] === 'function' ){
9
  });
10
  });
11
 
12
+ // Page navigation
13
+ $(document).on('click', '[data-page]', function(e){
14
+ var clicked = $(this),
15
+ page_box = clicked.closest('.caldera-form-page'),
16
+ form = clicked.closest('.caldera-grid'),
17
+ page = page_box.data('formpage'),
18
+ breadcrumb = $('.breadcrumb[data-form="' + form.prop('id') + '"]'),
19
+ next,
20
+ prev;
21
+
22
+ if(clicked.data('page') === 'next'){
23
+ if(breadcrumb){
24
+ breadcrumb.find('li.active').removeClass('active');
25
+ }
26
+ next = $('.caldera-form-page[data-formpage="'+ ( page + 1 ) +'"]');
27
+ if(next.length){
28
+ page_box.hide();
29
+ next.show();
30
+ if(breadcrumb){
31
+ breadcrumb.find('a[data-page="'+ ( page + 1 ) +'"]').parent().addClass('active');
32
+ }
33
+ }
34
+ }else if(clicked.data('page') === 'prev'){
35
+ if(breadcrumb){
36
+ breadcrumb.find('li.active').removeClass('active');
37
+ }
38
+ prev = $('.caldera-form-page[data-formpage="'+ ( page - 1 ) +'"]');
39
+ if(prev.length){
40
+ page_box.hide();
41
+ prev.show();
42
+ if(breadcrumb){
43
+ breadcrumb.find('a[data-page="'+ ( page - 1 ) +'"]').parent().addClass('active');
44
+ }
45
+ }
46
+ }else{
47
+ if(clicked.data('pagenav')){
48
+ e.preventDefault();
49
+ clicked.closest('.breadcrumb').find('li.active').removeClass('active');
50
+ $('#' + clicked.data('pagenav') + ' .caldera-form-page').hide();
51
+ $('.caldera-form-page[data-formpage="'+ ( clicked.data('page') ) +'"]').show();
52
+ clicked.parent().addClass('active');
53
+ }
54
+
55
+ }
56
+
57
+ $(document).trigger('cf.pagenav');
58
+
59
+ })
60
+ // init page errors
61
+ var tab_navclick;
62
+ $('.caldera-grid .breadcrumb').each(function(k,v){
63
+ $(v).find('a[data-pagenav]').each(function(i,e){
64
+ var tab = $(e),
65
+ form = tab.data('pagenav'),
66
+ page = $('.caldera-form-page[data-formpage="' + tab.data('page') + '"]');
67
+
68
+ if(page.find('.has-error').length){
69
+ tab.parent().addClass('error');
70
+ if(typeof tab_navclick === 'undefined'){
71
+ tab.trigger('click');
72
+ tab_navclick = true;
73
+ }
74
+
75
+ }
76
+
77
+ });
78
+ });
79
+ // trigger last page
80
+
81
+
82
+
83
  })(jQuery);
assets/js/jquery.baldrick.js CHANGED
@@ -233,9 +233,9 @@
233
  params.xhrFields = {
234
  onprogress: function (e) {
235
  if (e.lengthComputable) {
236
- console.log('Loaded '+ (e.loaded / e.total * 100) + '%');
237
  } else {
238
- console.log('Length not computable.');
239
  }
240
  }
241
  };
233
  params.xhrFields = {
234
  onprogress: function (e) {
235
  if (e.lengthComputable) {
236
+ //console.log('Loaded '+ (e.loaded / e.total * 100) + '%');
237
  } else {
238
+ //console.log('Length not computable.');
239
  }
240
  }
241
  };
assets/js/layout-grid.js CHANGED
@@ -1,4 +1,4 @@
1
- var rebuild_field_binding, rebind_field_bindings, current_form_fields = {}, required_errors = {};
2
 
3
  rebuild_field_binding = function(){
4
 
@@ -10,10 +10,12 @@ rebuild_field_binding = function(){
10
  fields.each(function(fk,fv){
11
  var field_id = jQuery(fv).prop('id'),
12
  label = jQuery('#' + field_id + '_lable').val(),
 
13
  type = jQuery('#' + field_id + '_type').val();
14
 
15
  current_form_fields[field_id] = {
16
  label: label,
 
17
  type: type
18
  };
19
 
@@ -25,25 +27,28 @@ rebuild_field_binding = function(){
25
 
26
  rebind_field_bindings = function(){
27
 
28
- var bindings = jQuery('.caldera-processor-field-bind');
 
 
29
 
30
  bindings.each(function(k,v){
31
 
32
  var field = jQuery(v),
33
  current = field.val(),
34
  default_sel = field.data('default'),
35
- count = 0;
 
 
 
 
36
 
37
-
38
- if(default_sel){
39
  current = default_sel;
40
  }
41
 
42
  field.empty();
43
 
44
- if(!field.hasClass('required')){
45
- field.append('<option value=""></option>');
46
- }
47
  for(var fid in current_form_fields){
48
  if(field.data('type')){
49
  if(field.data('type').split(',').indexOf(current_form_fields[fid].type) < 0){
@@ -51,17 +56,144 @@ rebind_field_bindings = function(){
51
  }
52
 
53
  }
54
- field.append('<option value="' + fid + '"' + ( current === fid ? 'selected="selected"' : '' ) + '>' + current_form_fields[fid].label + '</option>');
55
  count += 1;
56
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  if(count === 0){
59
- field.empty().append('<option value="">No ' + field.data('type').split(',').join(' or ') + ' in form</option>').prop('disabled', true);
 
 
 
 
60
  }else{
61
  field.prop('disabled', false);
62
  }
63
-
64
-
 
 
 
65
  });
66
 
67
  check_required_bindings();
@@ -75,6 +207,7 @@ function setup_field_type(obj){
75
 
76
 
77
  function check_required_bindings(){
 
78
  var fields = jQuery('.caldera-config-field .required'),
79
  savebutton = jQuery('.caldera-header-save-button'),
80
  field_elements = jQuery('.layout-form-field'),
@@ -89,6 +222,7 @@ function check_required_bindings(){
89
  jQuery('.error-tag').remove();
90
  //reset list
91
  required_errors = {};
 
92
  fields.each(function(k,v){
93
  if(!v.value.length){
94
  var field = jQuery(v),
@@ -112,12 +246,12 @@ function check_required_bindings(){
112
 
113
  }
114
  });
115
-
116
  for(var t in required_errors){
117
  savebutton.prop("disabled", true);
118
  jQuery('.caldera-forms-options-form').find('a[href="#' + t + '"]').append('<span class="error-tag">' + required_errors[t] + '</span>');
119
  }
120
-
121
  // check for button and update the processor page.
122
  if(!jQuery('.preview-caldera-config-group button:submit').length){
123
  //jQuery('.caldera-editor-processors-panel-wrap').hide();
@@ -135,46 +269,88 @@ function check_required_bindings(){
135
 
136
  jQuery(function($) {
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
  function buildLayoutString(){
140
- var capt = $('.layout-structure'),
141
- grid = $('.layout-grid'),
142
- rows = grid.find('.row'),
143
- struct = [];
144
- rows.each(function(k,v){
145
- var row = $(v),
146
- cols = row.children().not('.column-merge'),
147
- rowcols = [];
148
 
149
- cols.each(function(p, c){
150
- span = $(c).attr('class').split('-');
151
- rowcols.push(span[2]);
152
- var fields = $(c).find('.field-location');
153
- if(fields.length){
154
- fields.each(function(x,f){
155
- var field = $(f);
156
- field.val( (k+1) + ':' + (p+1) ).removeAttr('disabled');
157
- });
158
- }
159
- // set name
 
 
 
 
 
 
 
 
 
 
160
 
 
 
161
  });
162
- struct.push(rowcols.join(':'));
163
  });
164
- capt.val(struct.join('|'));
165
  }
166
 
167
- function insert_new_field(newfield, target){
168
  var name = "fld_" + Math.round( Math.random() * 10000000 ),
169
  new_name = name,
170
  field_conf = $('#field_config_panels'),
171
  new_conf_templ,
172
  new_field;
173
 
174
-
175
- // field conf template
176
- new_conf_templ = Handlebars.compile( $('#caldera_field_config_wrapper_templ').html() );
177
-
 
 
 
178
  new_field = {
179
  "id" : new_name,
180
  "label" : '',
@@ -202,11 +378,15 @@ jQuery(function($) {
202
 
203
  $('#' + name + '_lable').focus().select();
204
 
205
-
 
 
 
206
 
207
  rebuild_field_binding();
208
  baldrickTriggers();
209
  $('#' + name).trigger('field.drop');
 
210
  }
211
 
212
  function buildSortables(){
@@ -217,7 +397,7 @@ jQuery(function($) {
217
  });
218
 
219
 
220
- $( ".layout-grid-panel" ).sortable({
221
  placeholder: "row-drop-helper",
222
  handle: ".sort-handle",
223
  items: ".first-row-level",
@@ -228,9 +408,16 @@ jQuery(function($) {
228
  });
229
  $( ".layout-column" ).sortable({
230
  connectWith: ".layout-column",
 
231
  helper: "clone",
232
  items: ".layout-form-field",
233
  handle: ".drag-handle",
 
 
 
 
 
 
234
  stop: function(e,ui){
235
  ui.item.removeAttr('style');
236
  buildLayoutString();
@@ -242,7 +429,14 @@ jQuery(function($) {
242
  helper: "clone",
243
  appendTo: "body"
244
  });
245
-
 
 
 
 
 
 
 
246
  // Tools Bar Items
247
  $( ".layout-column" ).droppable({
248
  greedy: true,
@@ -262,7 +456,7 @@ jQuery(function($) {
262
  };
263
  buildSortables();
264
 
265
- $('.layout-grid-panel').on('click','.column-fieldinsert', function(e){
266
  //newfield-tool
267
  var target = $(this).closest('.column-container'),
268
  newfield = $('#newfield-tool').clone();
@@ -270,9 +464,18 @@ jQuery(function($) {
270
  insert_new_field(newfield, target);
271
 
272
  });
 
 
 
 
 
 
 
 
 
273
 
274
 
275
- $('.layout-grid-panel').on('click','.column-split', function(e){
276
  var column = $(this).parent().parent(),
277
  size = column.attr('class').split('-'),
278
  newcol = $('<div>').insertAfter(column);
@@ -292,9 +495,10 @@ jQuery(function($) {
292
  jQuery('.column-merge').remove();
293
 
294
  });
295
- $( ".layout-grid-panel" ).on('click', '.column-remove', function(e){
296
- var row = $(this).parent().parent().parent(),
297
- fields = row.find('.layout-form-field');
 
298
 
299
  //find fields
300
  if(fields.length){
@@ -311,7 +515,22 @@ jQuery(function($) {
311
  $(this).remove();
312
  buildLayoutString();
313
  rebuild_field_binding();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  });
 
315
  jQuery('.column-tools').remove();
316
  jQuery('.column-merge').remove();
317
 
@@ -319,12 +538,17 @@ jQuery(function($) {
319
 
320
  $( ".caldera-config-editor-main-panel" ).on('click', '.caldera-add-row', function(e){
321
  e.preventDefault();
322
- $('.layout-grid').append('<div class="first-row-level row"><div class="col-xs-12"><div class="layout-column column-container"></div></div></div>');
 
 
 
 
 
323
  buildSortables();
324
  buildLayoutString();
325
  });
326
 
327
- $( ".layout-grid-panel" ).on('click', '.column-join', function(e){
328
 
329
  var column = $(this).parent().parent().parent();
330
 
@@ -342,7 +566,7 @@ jQuery(function($) {
342
  jQuery('.column-merge').remove();
343
  });
344
 
345
- $('.layout-grid-panel').on('mouseenter','.row', function(e){
346
  var setrow = jQuery(this);
347
  jQuery('.column-tools,.column-merge').remove();
348
  setrow.children().children().first().append('<div class="column-remove column-tools"><i class="icon-remove"></i></div>');
@@ -421,12 +645,12 @@ jQuery(function($) {
421
  }
422
  });
423
  });
424
- $('.layout-grid').on('mouseleave','.row', function(e){
425
  jQuery('.column-tools').remove();
426
  jQuery('.column-merge').remove();
427
  });
428
 
429
- $('.layout-grid').on('click', '.layout-form-field .icon-remove', function(){
430
  var clicked = $(this),
431
  panel = clicked.parent(),
432
  config = $('#' + panel.data('config'));
@@ -437,10 +661,14 @@ jQuery(function($) {
437
  config.slideUp(100, function(){
438
  $(this).remove();
439
  });
 
 
 
 
440
 
441
  });
442
 
443
- $('.layout-grid').on('click', '.layout-form-field .icon-edit', function(){
444
 
445
 
446
 
@@ -456,6 +684,8 @@ jQuery(function($) {
456
  panel.addClass('field-edit-open');
457
  $('#' + panel.data('config')).show();
458
  }
 
 
459
  });
460
  $('body').on('click', '.layout-modal-edit-closer,.layout-modal-save-action', function(e){
461
 
@@ -564,11 +794,17 @@ jQuery(function($) {
564
 
565
 
566
  //toggle_option_row
567
-
568
  $('.caldera-editor-body').on('click', '.add-toggle-option', function(e){
569
 
570
- var clicked = $(this),
571
- wrapper = clicked.closest('.caldera-editor-field-config-wrapper'),
 
 
 
 
 
 
 
572
  toggle_rows = wrapper.find('.toggle-options'),
573
  row = $('#field-option-row-tmpl').html(),
574
  template = Handlebars.compile( row ),
@@ -578,28 +814,42 @@ jQuery(function($) {
578
  option : {}
579
  };
580
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
581
  // add new option
582
- config.option[key] = {
583
  value : '',
584
  label : '',
585
  default : false
586
  };
 
587
 
588
-
589
- // place new row
590
- toggle_rows.append( template( config ) );
591
-
592
-
593
-
594
- $('.toggle-options').sortable({
595
- handle: ".dashicons-sort"
596
- });
597
-
598
- toggle_rows.find('.toggle_value_field').last().focus();
599
 
600
 
 
 
 
 
 
 
601
  });
602
 
 
603
  // remove an option row
604
  $('.caldera-editor-body').on('click', '.toggle-remove-option', function(e){
605
  var triggerfield = $(this).closest('.caldera-editor-field-config-wrapper').find('.field-config').first();
@@ -607,20 +857,40 @@ jQuery(function($) {
607
  triggerfield.trigger('change');
608
  });
609
 
610
- $('.caldera-editor-body').on('blur', '.toggle_value_field', function(e){
611
- var value = $(this),
612
- label = value.next();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
613
 
614
- if(label.val().length){
 
 
 
615
  return;
616
  }
617
 
618
- label.val(value.val());
619
  });
620
 
621
  // build fild bindings
622
  rebuild_field_binding();
623
-
624
  });
625
 
626
 
1
+ var rebuild_field_binding, rebind_field_bindings, current_form_fields = {}, required_errors = {}, add_new_grid_page, add_page_grid;
2
 
3
  rebuild_field_binding = function(){
4
 
10
  fields.each(function(fk,fv){
11
  var field_id = jQuery(fv).prop('id'),
12
  label = jQuery('#' + field_id + '_lable').val(),
13
+ slug = jQuery('#' + field_id + '_slug').val(),
14
  type = jQuery('#' + field_id + '_type').val();
15
 
16
  current_form_fields[field_id] = {
17
  label: label,
18
+ slug: slug,
19
  type: type
20
  };
21
 
27
 
28
  rebind_field_bindings = function(){
29
 
30
+ var bindings = jQuery('.caldera-field-bind'),
31
+ type_instances,
32
+ processor_li;
33
 
34
  bindings.each(function(k,v){
35
 
36
  var field = jQuery(v),
37
  current = field.val(),
38
  default_sel = field.data('default'),
39
+ excludes = field.data('exclude'),
40
+ count = 0,
41
+ wrapper = field.closest('.caldera-editor-processor-config-wrapper'),
42
+ wrapper_id = wrapper.prop('id'),
43
+ valid;
44
 
45
+ if(default_sel){
 
46
  current = default_sel;
47
  }
48
 
49
  field.empty();
50
 
51
+ var optgroup = jQuery('<optgroup label="Fields">');
 
 
52
  for(var fid in current_form_fields){
53
  if(field.data('type')){
54
  if(field.data('type').split(',').indexOf(current_form_fields[fid].type) < 0){
56
  }
57
 
58
  }
59
+ optgroup.append('<option value="' + fid + '"' + ( current === fid ? 'selected="selected"' : '' ) + '>' + current_form_fields[fid].label + ' [' + current_form_fields[fid].slug + ']</option>');
60
  count += 1;
61
  }
62
+ optgroup.appendTo(field);
63
+ // system values
64
+ if(count === 0){
65
+ field.empty();
66
+ }
67
+
68
+ for(var type in system_values){
69
+ type_instances = [];
70
+
71
+ if(excludes){
72
+ if( excludes.split(',').indexOf(type) >= 0 ){
73
+ continue;
74
+ }
75
+ }
76
+
77
+ if(type !== 'system' ){
78
+ type_instance_confs = jQuery(".processor-" + type);
79
+
80
+ for(var c = 0; c<type_instance_confs.length; c++){
81
+ if(wrapper_id === type_instance_confs[c].id){
82
+ continue;
83
+ }
84
+
85
+ type_instances.push(type_instance_confs[c].id);
86
+ if(type_instance_confs.length > 1){
87
+ if(processor_li = jQuery('li.'+type_instance_confs[c].id + ' .processor-line-number')){
88
+ processor_li.html('[' + ( c + 1 ) + ']');
89
+ }
90
+ }
91
+
92
+ }
93
+ }else{
94
+ type_instances.push('__system__');
95
+ }
96
+
97
+ if(field.data('type')){
98
+
99
+ var types = field.data('type').split(',');
100
+
101
+ for(var t = 0; t<types.length; t++){
102
+ if(system_values[type].tags[types[t]]){
103
+
104
+ for( var instance = 0; instance < type_instances.length; instance++){
105
+
106
+ // check index order is valid
107
+ if(jQuery('li.'+type_instances[instance]).index() > jQuery('li.'+wrapper_id).index() && type_instances[instance] !== '__system__'){
108
+ //console.log('lower');
109
+ valid = ' disabled="disabled"';
110
+ }else{
111
+ valid = '';
112
+ }
113
+
114
+
115
+ var optgroup = jQuery('<optgroup label="' + system_values[type].type + ( type_instances[instance] !== '__system__' ? ' ' + ( jQuery('li.'+type_instances[instance]).find('.processor-line-number').html() ) : '' ) + '"' + valid + '>');
116
+
117
+ //for( var tag in system_values[type].tags){
118
+
119
+ for( var i = 0; i < system_values[type].tags[types[t]].length; i++){
120
+
121
+ var bind_value = system_values[type].tags[types[t]][i];
122
+ // update labels on multiple
123
+ if(type_instances[instance] !== '__system__'){
124
+ bind_value = bind_value.replace(type ,type_instances[instance]);
125
+ }
126
+
127
+ optgroup.append('<option value="{' + bind_value + '}"' + ( current === '{'+bind_value+'}' ? 'selected="selected"' : '' ) + valid + '>' + system_values[type].tags[types[t]][i] + '</option>');
128
+ //field.append('<option value="' + bind_value + '"' + ( current === system_values[type].tags[types[t]][i] ? 'selected="selected"' : '' ) + '>' + system_values[type].tags[types[t]][i] + '</option>');
129
+
130
+ count += 1;
131
+ }
132
+
133
+ //}
134
+ if(optgroup.children().length){
135
+ optgroup.appendTo(field);
136
+ }
137
+
138
+ }
139
 
140
+ }
141
+ }
142
+ }else{
143
+
144
+ if(system_values[type].tags.text){
145
+
146
+ for( var instance = 0; instance < type_instances.length; instance++){
147
+
148
+ // check index order is valid
149
+ if(jQuery('li.'+type_instances[instance]).index() > jQuery('li.'+wrapper_id).index() && type_instances[instance] !== '__system__'){
150
+ //console.log('lower');
151
+ valid = ' disabled="disabled"';
152
+ }else{
153
+ valid = '';
154
+ }
155
+
156
+ var optgroup = jQuery('<optgroup label="' + system_values[type].type + ( type_instances[instance] !== '__system__' ? ' ' + ( jQuery('li.'+type_instances[instance]).find('.processor-line-number').html() ) : '' ) + '"' + valid + '>');
157
+
158
+
159
+ for( var i = 0; i < system_values[type].tags.text.length; i++){
160
+
161
+ var bind_value = system_values[type].tags.text[i];
162
+ // update labels on multiple
163
+ if(type_instances[instance] !== '__system__'){
164
+ bind_value = bind_value.replace(type ,type_instances[instance]);
165
+ }
166
+
167
+ optgroup.append('<option value="{' + bind_value + '}"' + ( current === '{'+bind_value+'}' ? 'selected="selected"' : '' ) + valid + '>' + system_values[type].tags.text[i] + '</option>');
168
+ count += 1;
169
+
170
+ }
171
+
172
+ if(optgroup.children().length){
173
+ optgroup.appendTo(field);
174
+ }
175
+
176
+ }
177
+
178
+ }
179
+
180
+ }
181
+
182
+ }
183
  if(count === 0){
184
+ field.empty();
185
+ if(field.data('type')){
186
+ field.append('<option value="">No ' + field.data('type').split(',').join(' or ') + ' in form</option>').prop('disabled', true);
187
+ var no_options = true;
188
+ }
189
  }else{
190
  field.prop('disabled', false);
191
  }
192
+
193
+ if(!field.hasClass('required') && typeof no_options === 'undefined'){
194
+ field.prepend('<option value=""></option>');
195
+ }
196
+ field.val(current);
197
  });
198
 
199
  check_required_bindings();
207
 
208
 
209
  function check_required_bindings(){
210
+
211
  var fields = jQuery('.caldera-config-field .required'),
212
  savebutton = jQuery('.caldera-header-save-button'),
213
  field_elements = jQuery('.layout-form-field'),
222
  jQuery('.error-tag').remove();
223
  //reset list
224
  required_errors = {};
225
+
226
  fields.each(function(k,v){
227
  if(!v.value.length){
228
  var field = jQuery(v),
246
 
247
  }
248
  });
249
+
250
  for(var t in required_errors){
251
  savebutton.prop("disabled", true);
252
  jQuery('.caldera-forms-options-form').find('a[href="#' + t + '"]').append('<span class="error-tag">' + required_errors[t] + '</span>');
253
  }
254
+
255
  // check for button and update the processor page.
256
  if(!jQuery('.preview-caldera-config-group button:submit').length){
257
  //jQuery('.caldera-editor-processors-panel-wrap').hide();
269
 
270
  jQuery(function($) {
271
 
272
+ add_new_grid_page = function(obj){
273
+ return { "page_no" : "pg_" + Math.round( Math.random() * 10000000 ) };
274
+ }
275
+
276
+ add_page_grid = function(obj){
277
+ //obj.rawData.page_no
278
+ var btn_count = $('.page-toggle').length + 1,
279
+ button = $('<button type="button" data-name="Page ' + btn_count + '" data-page="' + obj.rawData.page_no + '" class="page-toggle button">' + obj.params.trigger.data('addtitle') + ' ' + btn_count + '</button> '),
280
+ option_tab = $('#page-toggles');
281
+ button.appendTo( option_tab );
282
+ option_tab.show();
283
+ buildSortables();
284
+ button.trigger('click');
285
+ if( btn_count === 1){
286
+ option_tab.hide();
287
+ }
288
+ $(document).trigger('add.page');
289
+ }
290
+
291
+ // bind pages tab
292
+ $(document).on('remove.page add.page load.page', function(e){
293
+ var btn_count = $('.page-toggle').length,
294
+ pages_tab = $('#tab_pages');
295
+
296
+ if(btn_count <= 1){
297
+ pages_tab.hide();
298
+ }else{
299
+ pages_tab.show();
300
+ }
301
+
302
+
303
+ });
304
 
305
  function buildLayoutString(){
306
+ var grid_panels = $('.layout-grid-panel'),
307
+ row_index = 0;
308
+
309
+ grid_panels.each(function(pk,pv){
 
 
 
 
310
 
311
+ var panel= $(pv),
312
+ capt = panel.find('.layout-structure'),
313
+ rows = panel.find('.row'),
314
+ struct = [];
315
+
316
+ rows.each(function(k,v){
317
+ var row = $(v),
318
+ cols = row.children().not('.column-merge'),
319
+ rowcols = [];
320
+ row_index += 1;
321
+ cols.each(function(p, c){
322
+ span = $(c).attr('class').split('-');
323
+ rowcols.push(span[2]);
324
+ var fields = $(c).find('.field-location');
325
+ if(fields.length){
326
+ fields.each(function(x,f){
327
+ var field = $(f);
328
+ field.val( row_index + ':' + (p+1) ).removeAttr('disabled');
329
+ });
330
+ }
331
+ // set name
332
 
333
+ });
334
+ struct.push(rowcols.join(':'));
335
  });
336
+ capt.val(struct.join('|'));
337
  });
 
338
  }
339
 
340
+ function insert_new_field(newfield, target, tel){
341
  var name = "fld_" + Math.round( Math.random() * 10000000 ),
342
  new_name = name,
343
  field_conf = $('#field_config_panels'),
344
  new_conf_templ,
345
  new_field;
346
 
347
+ if(tel){
348
+ var clone = $('#' + tel).clone().wrap('<div>').parent().html().replace( new RegExp(tel,"g") , '{{id}}');
349
+ new_conf_templ = Handlebars.compile( clone );
350
+ }else{
351
+ // field conf template
352
+ new_conf_templ = Handlebars.compile( $('#caldera_field_config_wrapper_templ').html() );
353
+ }
354
  new_field = {
355
  "id" : new_name,
356
  "label" : '',
378
 
379
  $('#' + name + '_lable').focus().select();
380
 
381
+ if(tel){
382
+ field_conf.find('.field_config_string').val('');
383
+ field_conf.find('.field-label').trigger('change');
384
+ }
385
 
386
  rebuild_field_binding();
387
  baldrickTriggers();
388
  $('#' + name).trigger('field.drop');
389
+ $(document).trigger('field.added');
390
  }
391
 
392
  function buildSortables(){
397
  });
398
 
399
 
400
+ $( "#grid-pages-panel" ).sortable({
401
  placeholder: "row-drop-helper",
402
  handle: ".sort-handle",
403
  items: ".first-row-level",
408
  });
409
  $( ".layout-column" ).sortable({
410
  connectWith: ".layout-column",
411
+ appendTo: "#grid-pages-panel",
412
  helper: "clone",
413
  items: ".layout-form-field",
414
  handle: ".drag-handle",
415
+ cursor: "move",
416
+ opacity: 0.7,
417
+ cursorAt: {left: 100, top: 15},
418
+ start: function(e,ui){
419
+ ui.helper.css({width: '200px', height: '35px', paddingTop: '20px'});
420
+ },
421
  stop: function(e,ui){
422
  ui.item.removeAttr('style');
423
  buildLayoutString();
429
  helper: "clone",
430
  appendTo: "body"
431
  });
432
+ $('.page-toggle.button').droppable({
433
+ accept: ".layout-form-field",
434
+ over: function(e, ui){
435
+ $(this).trigger('click');
436
+ //buildSortables();
437
+ $( ".layout-column" ).sortable("refresh");
438
+ }
439
+ });
440
  // Tools Bar Items
441
  $( ".layout-column" ).droppable({
442
  greedy: true,
456
  };
457
  buildSortables();
458
 
459
+ $('#grid-pages-panel').on('click','.column-fieldinsert', function(e){
460
  //newfield-tool
461
  var target = $(this).closest('.column-container'),
462
  newfield = $('#newfield-tool').clone();
464
  insert_new_field(newfield, target);
465
 
466
  });
467
+ /*
468
+ $('#grid-pages-panel').on('click','.icon-filter', function(e){
469
+ //newfield-tool
470
+ var target = $(this).closest('.column-container'),
471
+ newfield = $('#newfield-tool').clone();
472
+
473
+ insert_new_field(newfield, target, $(this).data('id'));
474
+
475
+ });*/
476
 
477
 
478
+ $('#grid-pages-panel').on('click','.column-split', function(e){
479
  var column = $(this).parent().parent(),
480
  size = column.attr('class').split('-'),
481
  newcol = $('<div>').insertAfter(column);
495
  jQuery('.column-merge').remove();
496
 
497
  });
498
+ $( "#grid-pages-panel" ).on('click', '.column-remove', function(e){
499
+ var row = $(this).closest('.row'),
500
+ fields = row.find('.layout-form-field'),
501
+ wrap = row.closest('.layout-grid-panel');
502
 
503
  //find fields
504
  if(fields.length){
515
  $(this).remove();
516
  buildLayoutString();
517
  rebuild_field_binding();
518
+ if(!wrap.find('.row').length){
519
+ wrap.remove();
520
+ var btn = $('#page-toggles .button-primary'),
521
+ prev = btn.prev(),
522
+ next = btn.next();
523
+
524
+ btn.remove();
525
+ if(prev.length){
526
+ prev.trigger('click');
527
+ }else{
528
+ next.trigger('click');
529
+ }
530
+ }
531
+ $(document).trigger('remove.page');
532
  });
533
+
534
  jQuery('.column-tools').remove();
535
  jQuery('.column-merge').remove();
536
 
538
 
539
  $( ".caldera-config-editor-main-panel" ).on('click', '.caldera-add-row', function(e){
540
  e.preventDefault();
541
+ var wrap = $('.page-active');
542
+ if(!wrap.length){
543
+ $('.caldera-add-page').trigger('click');
544
+ return;
545
+ }
546
+ $('.page-active').append('<div class="first-row-level row"><div class="col-xs-12"><div class="layout-column column-container"></div></div></div>');
547
  buildSortables();
548
  buildLayoutString();
549
  });
550
 
551
+ $( "#grid-pages-panel" ).on('click', '.column-join', function(e){
552
 
553
  var column = $(this).parent().parent().parent();
554
 
566
  jQuery('.column-merge').remove();
567
  });
568
 
569
+ $('#grid-pages-panel').on('mouseenter','.row', function(e){
570
  var setrow = jQuery(this);
571
  jQuery('.column-tools,.column-merge').remove();
572
  setrow.children().children().first().append('<div class="column-remove column-tools"><i class="icon-remove"></i></div>');
645
  }
646
  });
647
  });
648
+ $('#grid-pages-panel').on('mouseleave','.row', function(e){
649
  jQuery('.column-tools').remove();
650
  jQuery('.column-merge').remove();
651
  });
652
 
653
+ $('#grid-pages-panel').on('click', '.layout-form-field .icon-remove', function(){
654
  var clicked = $(this),
655
  panel = clicked.parent(),
656
  config = $('#' + panel.data('config'));
661
  config.slideUp(100, function(){
662
  $(this).remove();
663
  });
664
+ //if(!wrap.children().length){
665
+ //wrap.remove();
666
+
667
+ //}
668
 
669
  });
670
 
671
+ $('#grid-pages-panel').on('click', '.layout-form-field .icon-edit', function(){
672
 
673
 
674
 
684
  panel.addClass('field-edit-open');
685
  $('#' + panel.data('config')).show();
686
  }
687
+
688
+ $(document).trigger('show.' + panel.data('config'));
689
  });
690
  $('body').on('click', '.layout-modal-edit-closer,.layout-modal-save-action', function(e){
691
 
794
 
795
 
796
  //toggle_option_row
 
797
  $('.caldera-editor-body').on('click', '.add-toggle-option', function(e){
798
 
799
+ var clicked = $(this);
800
+
801
+ if(clicked.data('bulk')){
802
+ $(clicked.data('bulk')).toggle();
803
+ $(clicked.data('bulk')).find('textarea').focus();
804
+ return;
805
+ }
806
+
807
+ var wrapper = clicked.closest('.caldera-editor-field-config-wrapper'),
808
  toggle_rows = wrapper.find('.toggle-options'),
809
  row = $('#field-option-row-tmpl').html(),
810
  template = Handlebars.compile( row ),
814
  option : {}
815
  };
816
 
817
+ if(clicked.data('options')){
818
+ var batchinput = $(clicked.data('options')),
819
+ batch = batchinput.val().split("\n");
820
+ for( var i = 0; i < batch.length; i ++){
821
+ config.option["opt" + parseInt( ( Math.random() + i ) * 0x100000 )] = {
822
+ value : batch[i],
823
+ label : batch[i],
824
+ default : false
825
+ }
826
+ }
827
+ $(clicked.data('options')).parent().hide();
828
+ batchinput.val('');
829
+ toggle_rows.empty();
830
+ }else{
831
  // add new option
832
+ config.option[key] = {
833
  value : '',
834
  label : '',
835
  default : false
836
  };
837
+ }
838
 
839
+ // place new row
840
+ toggle_rows.append( template( config ) );
841
+ wrapper.find('.toggle_show_values').trigger('change');
 
 
 
 
 
 
 
 
842
 
843
 
844
+ $('.toggle-options').sortable({
845
+ handle: ".dashicons-sort"
846
+ });
847
+ if(!batch){
848
+ toggle_rows.find('.toggle_label_field').last().focus();
849
+ }
850
  });
851
 
852
+
853
  // remove an option row
854
  $('.caldera-editor-body').on('click', '.toggle-remove-option', function(e){
855
  var triggerfield = $(this).closest('.caldera-editor-field-config-wrapper').find('.field-config').first();
857
  triggerfield.trigger('change');
858
  });
859
 
860
+ $('.caldera-editor-body').on('click', '.page-toggle', function(e){
861
+ var clicked = $(this),
862
+ wrap = clicked.parent(),
863
+ btns = wrap.find('.button');
864
+
865
+ btns.removeClass('button-primary');
866
+ $('.layout-grid-panel').hide().removeClass('page-active');
867
+ $('#' + clicked.data('page')).show().addClass('page-active');
868
+ clicked.addClass('button-primary');
869
+ //reindex
870
+ btns.each(function(k,v){
871
+ $(v).html(wrap.data('title') + ' ' + (k+1) );
872
+ });
873
+ if(btns.length === 1){
874
+ wrap.hide();
875
+ }
876
+
877
+ });
878
+
879
+ $('.caldera-editor-body').on('blur toggle.values', '.toggle_label_field', function(e){
880
 
881
+ var label = $(this),
882
+ value = label.prev();
883
+
884
+ if(value.val().length){
885
  return;
886
  }
887
 
888
+ value.val(label.val());
889
  });
890
 
891
  // build fild bindings
892
  rebuild_field_binding();
893
+ $(document).trigger('load.page');
894
  });
895
 
896
 
assets/js/processors-edit.js CHANGED
@@ -4,7 +4,11 @@ jQuery(function($){
4
 
5
  function build_sortables(){
6
  // set sortable groups
7
- $( ".caldera-editor-processors-panel ul" ).sortable();
 
 
 
 
8
 
9
  }
10
 
@@ -32,7 +36,8 @@ jQuery(function($){
32
 
33
  new_templ = Handlebars.compile( $('#processor-line-tmpl').html() );
34
  new_proc = {
35
- "id" : "fp_" + processid
 
36
  };
37
 
38
  // place new group line
@@ -55,7 +60,8 @@ jQuery(function($){
55
  $('body').on('click', '.delete-processor', function(e){
56
 
57
  var clicked = $(this),
58
- parent = clicked.closest('.caldera-editor-processor-config-wrapper');
 
59
 
60
  if(!confirm(clicked.data('confirm'))){
61
  return;
@@ -66,7 +72,8 @@ jQuery(function($){
66
 
67
  $('.caldera-processor-nav a').first().trigger('click');
68
 
69
- check_required_bindings();
 
70
 
71
  });
72
 
@@ -83,7 +90,7 @@ jQuery(function($){
83
  }
84
 
85
  title_line.html( title );
86
- activeline.html( title ).parent().addClass( 'processor_type_' + selected.val() );
87
 
88
  // get config
89
  build_processor_config(this);
@@ -154,19 +161,32 @@ jQuery(function($){
154
  build_processor_config(v);
155
  });
156
 
 
 
157
  });//
158
 
159
 
160
  // field binding helper
161
  Handlebars.registerHelper('_field', function(args) {
162
 
163
- var config = this,required="";
 
 
164
 
165
  if(args.hash.required){
166
  required = " required";
167
  }
 
 
 
 
 
 
 
 
 
168
 
169
- out = '<select ' + ( args.hash.type ? 'data-type="' + args.hash.type + '"' : '' ) + ' name="' + this._name + '[' + args.hash.slug + ']" id="' + this._id + '_' + args.hash.slug + '" class="block-input caldera-processor-field-bind' + required + '">';
170
 
171
  if(!args.hash.required){
172
  out += '<option value=""></option>';
@@ -189,15 +209,19 @@ Handlebars.registerHelper('_field', function(args) {
189
  }
190
 
191
 
192
- out += '<option value="' + fid + '"' + sel + '>' + current_form_fields[fid].label + '</option>';
193
  };
194
 
195
  out += '</select>';
196
-
 
 
197
  return out;
198
  });
199
 
200
-
 
 
201
 
202
 
203
 
4
 
5
  function build_sortables(){
6
  // set sortable groups
7
+ $( ".caldera-editor-processors-panel ul" ).sortable({
8
+ update: function(){
9
+ rebind_field_bindings();
10
+ }
11
+ });
12
 
13
  }
14
 
36
 
37
  new_templ = Handlebars.compile( $('#processor-line-tmpl').html() );
38
  new_proc = {
39
+ "id" : "fp_" + processid,
40
+ "type" : clicked.data('type')
41
  };
42
 
43
  // place new group line
60
  $('body').on('click', '.delete-processor', function(e){
61
 
62
  var clicked = $(this),
63
+ parent = clicked.closest('.caldera-editor-processor-config-wrapper'),
64
+ type = parent.data('type');
65
 
66
  if(!confirm(clicked.data('confirm'))){
67
  return;
72
 
73
  $('.caldera-processor-nav a').first().trigger('click');
74
 
75
+ //check_required_bindings();
76
+ rebuild_field_binding();
77
 
78
  });
79
 
90
  }
91
 
92
  title_line.html( title );
93
+ activeline.html( title + ' <span class="processor-line-number"></span>' ).parent().addClass( 'processor_type_' + selected.val() );
94
 
95
  // get config
96
  build_processor_config(this);
161
  build_processor_config(v);
162
  });
163
 
164
+
165
+ build_sortables();
166
  });//
167
 
168
 
169
  // field binding helper
170
  Handlebars.registerHelper('_field', function(args) {
171
 
172
+ var config = this,required="", is_array = "", exclude="";
173
+
174
+ var default_val = this[args.hash.slug] ? ' data-default="' + this[args.hash.slug] + '"' : '';
175
 
176
  if(args.hash.required){
177
  required = " required";
178
  }
179
+ if(args.hash.exclude){
180
+ exclude = 'data-exclude="'+args.hash.exclude+'"';
181
+ }
182
+ if(args.hash.array){
183
+ is_array = "[]";
184
+ if(args.hash.array !== 'true'){
185
+ default_val = 'data-default="' + args.hash.array + '"';
186
+ }
187
+ }
188
 
189
+ out = '<select ' + ( args.hash.type ? 'data-type="' + args.hash.type + '"' : '' ) + default_val +' ' + exclude + ' name="' + this._name + '[' + args.hash.slug + ']' + is_array + '" id="' + this._id + '_' + args.hash.slug + '" class="block-input field-config caldera-field-bind' + required + '">';
190
 
191
  if(!args.hash.required){
192
  out += '<option value=""></option>';
209
  }
210
 
211
 
212
+ out += '<option value="' + fid + '"' + sel + '>' + current_form_fields[fid].label + ' [' + current_form_fields[fid].slug + ']</option>';
213
  };
214
 
215
  out += '</select>';
216
+ if(args.hash.required){
217
+ out += '<input class="field-config" name="' + this._name + '[_required_bounds][]" type="hidden" value="' + args.hash.slug + '">';
218
+ }
219
  return out;
220
  });
221
 
222
+ Handlebars.registerHelper('console', function(context, options) {
223
+ console.log(this);
224
+ });
225
 
226
 
227
 
caldera-core.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin URI: http://digilab.co.za
5
  Description: Create simple to complex grid based, responsive forms quickly and easily.
6
  Author: David Cramer
7
- Version: 1.0.0
8
  Author URI: http://digilab.co.za
9
  */
10
 
@@ -17,14 +17,18 @@ if ( ! defined( 'WPINC' ) ) {
17
 
18
  define('CFCORE_PATH', plugin_dir_path(__FILE__));
19
  define('CFCORE_URL', plugin_dir_url(__FILE__));
20
- define('CFCORE_VER', '1.0.0');
21
  define('CFCORE_EXTEND_URL', 'http://digilab.co.za');
22
 
23
- // table builder
24
- register_activation_hook( __FILE__, array( 'Caldera_Forms_Admin', 'activate_caldera_forms' ) );
25
-
26
  include_once CFCORE_PATH . 'classes/core.php';
27
  include_once CFCORE_PATH . 'classes/widget.php';
 
 
 
 
 
 
 
28
 
29
  add_action( 'plugins_loaded', array( 'Caldera_Forms', 'get_instance' ) );
30
 
4
  Plugin URI: http://digilab.co.za
5
  Description: Create simple to complex grid based, responsive forms quickly and easily.
6
  Author: David Cramer
7
+ Version: 1.0.91
8
  Author URI: http://digilab.co.za
9
  */
10
 
17
 
18
  define('CFCORE_PATH', plugin_dir_path(__FILE__));
19
  define('CFCORE_URL', plugin_dir_url(__FILE__));
20
+ define('CFCORE_VER', '1.0.91');
21
  define('CFCORE_EXTEND_URL', 'http://digilab.co.za');
22
 
 
 
 
23
  include_once CFCORE_PATH . 'classes/core.php';
24
  include_once CFCORE_PATH . 'classes/widget.php';
25
+ // includes
26
+ include_once CFCORE_PATH . 'includes/cf-ajax/plugin.php';
27
+ include_once CFCORE_PATH . 'includes/field_processors.php';
28
+ include_once CFCORE_PATH . 'includes/custom_field_class.php';
29
+
30
+ // table builder
31
+ register_activation_hook( __FILE__, array( 'Caldera_Forms', 'activate_caldera_forms' ) );
32
 
33
  add_action( 'plugins_loaded', array( 'Caldera_Forms', 'get_instance' ) );
34
 
classes/admin.php CHANGED
@@ -39,6 +39,7 @@ class Caldera_Forms_Admin {
39
  */
40
  private function __construct() {
41
 
 
42
  // Load plugin text domain
43
  add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
44
 
@@ -49,13 +50,13 @@ class Caldera_Forms_Admin {
49
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_stylescripts' ) );
50
 
51
  // add element & fields filters
52
- add_filter('caldera_forms_get_panel_extensions', array( $this, 'get_panel_extensions'));
53
  add_filter('caldera_forms_entry_viewer_buttons', array( $this, 'set_viewer_buttons'),10, 4);
54
 
55
  // action
56
  add_action('caldera_forms_entry_actions', array( $this, 'get_entry_actions'),1);
57
  add_action('caldera_forms_admin_templates', array( $this, 'get_admin_templates'),1);
58
-
59
 
60
  add_action( 'wp_loaded', array( $this, 'save_form') );
61
  add_action( 'media_buttons', array($this, 'shortcode_insert_button' ), 11 );
@@ -64,11 +65,80 @@ class Caldera_Forms_Admin {
64
  add_action("wp_ajax_browse_entries", array( $this, 'browse_entries') );
65
  add_action("wp_ajax_save_cf_setting", array( $this, 'save_cf_setting') );
66
  add_action("wp_ajax_cf_dismiss_pointer", array( $this, 'update_pointer') );
 
 
 
 
 
 
 
67
 
68
- add_action( 'admin_footer', array( $this, 'add_shortcode_inserter'));
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
71
 
 
72
  public static function update_pointer(){
73
 
74
  if(!empty($_POST['pointer'])){
@@ -104,7 +174,26 @@ class Caldera_Forms_Admin {
104
  public static function get_admin_templates(){
105
  include CFCORE_PATH . 'ui/admin_templates.php';
106
  }
107
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  public static function get_entry_actions(){
110
 
@@ -123,7 +212,8 @@ class Caldera_Forms_Admin {
123
  $viewer_buttons = 'data-modal-buttons=\'' . implode(';', $viewer_buttons) . '\'';
124
  }
125
 
126
- echo '<button class="button button-small ajax-trigger" data-active-class="none" data-load-class="spinner" ' . $viewer_buttons . ' data-group="viewentry" data-entry="{{_entry_id}}" data-form="{{../form}}" data-action="get_entry" data-modal="view_entry" data-modal-width="550" data-modal-title="' . __('Entry', 'caldera-forms') . ' # {{_entry_id}}" data-template="#view-entry-tmpl" type="button">' . __('View', 'caldera-forms') . '</button> ';
 
127
  }
128
 
129
  public static function set_viewer_buttons($buttons){
@@ -168,49 +258,6 @@ class Caldera_Forms_Admin {
168
  }
169
 
170
 
171
- /// activator
172
- public static function activate_caldera_forms(){
173
- global $wpdb;
174
-
175
- $tables = $wpdb->get_results("SHOW TABLES", ARRAY_A);
176
- foreach($tables as $table){
177
- $alltables[] = implode($table);
178
- }
179
- if(!in_array($wpdb->prefix.'cf_form_entries', $alltables)){
180
- // create tables
181
- require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
182
-
183
- $entry_table = "CREATE TABLE `" . $wpdb->prefix . "cf_form_entries` (
184
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
185
- `form_id` varchar(18) NOT NULL DEFAULT '',
186
- `user_id` int(11) NOT NULL,
187
- `datestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
188
- PRIMARY KEY (`id`),
189
- KEY `form_id` (`form_id`),
190
- KEY `user_id` (`user_id`),
191
- KEY `date_time` (`datestamp`)
192
- ) DEFAULT CHARSET=utf8;";
193
-
194
-
195
- dbDelta( $entry_table );
196
-
197
- $values_table = "CREATE TABLE `" . $wpdb->prefix . "cf_form_entry_values` (
198
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
199
- `entry_id` int(11) NOT NULL,
200
- `slug` varchar(255) NOT NULL DEFAULT '',
201
- `value` longtext NOT NULL,
202
- PRIMARY KEY (`id`),
203
- KEY `form_id` (`entry_id`),
204
- KEY `slug` (`slug`)
205
- ) DEFAULT CHARSET=utf8;";
206
-
207
- dbDelta( $values_table );
208
-
209
- }
210
-
211
- }
212
-
213
-
214
  public static function browse_entries(){
215
 
216
  global $wpdb;
@@ -225,7 +272,9 @@ class Caldera_Forms_Admin {
225
  $selects = array();
226
 
227
  // get all fieldtype
228
- $field_types = apply_filters('caldera_forms_get_field_types', array() );
 
 
229
  $fields = array();
230
  if(!empty($form['fields'])){
231
  foreach($form['fields'] as $fid=>$field){
@@ -248,7 +297,28 @@ class Caldera_Forms_Admin {
248
 
249
  $data = array();
250
 
251
- $data['total'] = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(`id`) AS `total` FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `form_id` = %s;", $_POST['form']));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
  $data['pages'] = ceil($data['total'] / $perpage );
254
 
@@ -269,24 +339,30 @@ class Caldera_Forms_Admin {
269
  $offset = ($page - 1) * $perpage;
270
  $limit = $offset . ',' . $perpage;
271
 
 
 
 
 
 
272
  $rawdata = $wpdb->get_results($wpdb->prepare("
273
  SELECT
274
- `id`
 
275
  FROM `" . $wpdb->prefix ."cf_form_entries`
276
 
277
- WHERE `form_id` = %s ORDER BY `datestamp` DESC LIMIT " . $limit . ";", $_POST['form'] ));
278
 
279
  if(!empty($rawdata)){
280
 
 
 
 
 
281
  $ids = array();
282
  foreach($rawdata as $row){
283
  $ids[] = $row->id;
284
  }
285
 
286
- $filter = null;
287
- if(!empty($selects)){
288
- //$filter .= " AND `value`.`slug` IN (" . implode(',', $selects) . ") ";
289
- }
290
  $rawdata = $wpdb->get_results("
291
  SELECT
292
  `entry`.`id` as `_entryid`,
@@ -307,17 +383,18 @@ class Caldera_Forms_Admin {
307
  $dateformat = get_option('date_format');
308
  $timeformat = get_option('time_format');
309
  foreach($rawdata as $row){
310
-
311
  if(!empty($row->_user_id)){
312
  $user = get_userdata( $row->_user_id );
313
- $data['entries']['E' . $row->_entryid]['user']['ID'] = $user->ID;
314
- $data['entries']['E' . $row->_entryid]['user']['name'] = $user->data->display_name;
315
- $data['entries']['E' . $row->_entryid]['user']['email'] = $user->data->user_email;
316
- $data['entries']['E' . $row->_entryid]['user']['avatar'] = get_avatar( $user->ID, 64 );
 
 
317
  }
318
  $data['entries']['E' . $row->_entryid]['_entry_id'] = $row->_entryid;
319
  $data['entries']['E' . $row->_entryid]['_date'] = date_i18n( $dateformat.' '.$timeformat, strtotime($row->_date_submitted), $gmt_offset);
320
- $label = $row->slug;
321
  // setup default data array
322
  if(!isset($data['entries']['E' . $row->_entryid]['data'])){
323
  if(isset($field_labels)){
@@ -328,24 +405,14 @@ class Caldera_Forms_Admin {
328
  }
329
  }
330
 
331
- //print_r($field_labels);
332
- if(!empty($field_labels[$label])){
333
- $label = $field_labels[$label];
334
 
335
  // check view handler
336
  $field = $fields[$row->slug];
337
 
338
- if(isset($field_types[$field['type']]['viewer'])){
339
-
340
- if(is_array($field_types[$field['type']]['viewer'])){
341
- $row->value = call_user_func_array($field_types[$field['type']]['viewer'],array($row->value, $field, $form));
342
- }else{
343
- if(function_exists($field_types[$field['type']]['viewer'])){
344
- $func = $field_types[$field['type']]['viewer'];
345
- $row->value = $func($row->value, $field, $form);
346
- }
347
- }
348
- }
349
 
350
 
351
  if(isset($data['entries']['E' . $row->_entryid]['data'][$row->slug])){
@@ -359,11 +426,14 @@ class Caldera_Forms_Admin {
359
  $data['entries']['E' . $row->_entryid]['data'][$row->slug] = $row->value;
360
  }
361
  }
362
- //ksort($data['entries']['E' . $row->_entryid]['data']);
363
  }
364
  }
365
  }
366
 
 
 
 
367
  header('Content-Type: application/json');
368
  echo json_encode( $data );
369
  exit;
@@ -441,14 +511,22 @@ class Caldera_Forms_Admin {
441
  wp_enqueue_script( 'jquery-ui-droppable' );
442
 
443
  }
 
 
 
 
 
444
  // Load Field Types Styles & Scripts
445
  $field_types = apply_filters('caldera_forms_get_field_types', array() );
446
 
447
- // load element types
448
  $panel_extensions = apply_filters('caldera_forms_get_panel_extensions', array() );
449
 
 
 
 
450
  // merge a list
451
- $merged_types = array_merge($field_types, $panel_extensions);
452
 
453
  foreach( $merged_types as $type=>&$config){
454
 
@@ -544,8 +622,8 @@ class Caldera_Forms_Admin {
544
  echo "<form method=\"POST\" action=\"admin.php?page=" . $this->plugin_slug . "\" data-load-element=\"#save_indicator\" data-sender=\"ajax\" class=\"caldera-forms-options-form edit-update-trigger\">\r\n";
545
  include CFCORE_PATH . 'ui/edit.php';
546
  echo "</form>\r\n";
547
- }elseif(!empty($_GET['project'])){
548
- include CFCORE_PATH . 'ui/project.php';
549
  }else{
550
  include CFCORE_PATH . 'ui/admin.php';
551
  }
@@ -583,7 +661,80 @@ class Caldera_Forms_Admin {
583
  }
584
 
585
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
 
 
587
  if(!empty($_GET['export'])){
588
 
589
  $form = get_option( $_GET['export'] );
@@ -597,6 +748,16 @@ class Caldera_Forms_Admin {
597
  $labels[$field['slug']] = $field['label'];
598
  }
599
  }
 
 
 
 
 
 
 
 
 
 
600
 
601
  $rawdata = $wpdb->get_results($wpdb->prepare("
602
  SELECT
@@ -610,7 +771,7 @@ class Caldera_Forms_Admin {
610
  LEFT JOIN `" . $wpdb->prefix ."cf_form_entry_values` AS `value` ON (`entry`.`id` = `value`.`entry_id`)
611
 
612
  WHERE `entry`.`form_id` = %s
613
-
614
  ORDER BY `entry`.`datestamp` DESC;", $_GET['export']));
615
 
616
  $data = array();
@@ -671,19 +832,30 @@ class Caldera_Forms_Admin {
671
  }
672
 
673
  if( isset($_POST['config']) && isset( $_POST['cf_edit_nonce'] ) ){
674
-
675
  // if this fails, check_admin_referer() will automatically print a "failed" page and die.
676
  if ( check_admin_referer( 'cf_edit_element', 'cf_edit_nonce' ) ) {
677
-
678
  // strip slashes
679
- $data = stripslashes_deep($_POST['config']);
680
-
681
  // get form registry
682
  $forms = get_option( '_caldera_forms' );
683
  if(empty($forms)){
684
  $forms = array();
685
  }
686
-
 
 
 
 
 
 
 
 
 
 
 
 
687
  // add form to registry
688
  $forms[$data['ID']] = $data;
689
 
@@ -701,6 +873,9 @@ class Caldera_Forms_Admin {
701
  unset($forms[$data['ID']]['settings']);
702
  }
703
 
 
 
 
704
  // add from to list
705
  update_option($data['ID'], $data);
706
  do_action('caldera_forms_save_form', $data);
@@ -790,6 +965,12 @@ class Caldera_Forms_Admin {
790
  "canvas" => $path . "layout.php",
791
  "side_panel" => $path . "layout_side.php",
792
  ),
 
 
 
 
 
 
793
  "processors" => array(
794
  "name" => __("Processors", 'caldera-forms'),
795
  "location" => "lower",
39
  */
40
  private function __construct() {
41
 
42
+
43
  // Load plugin text domain
44
  add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
45
 
50
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_stylescripts' ) );
51
 
52
  // add element & fields filters
53
+ add_filter('caldera_forms_get_panel_extensions', array( $this, 'get_panel_extensions'), 1);
54
  add_filter('caldera_forms_entry_viewer_buttons', array( $this, 'set_viewer_buttons'),10, 4);
55
 
56
  // action
57
  add_action('caldera_forms_entry_actions', array( $this, 'get_entry_actions'),1);
58
  add_action('caldera_forms_admin_templates', array( $this, 'get_admin_templates'),1);
59
+ add_action('caldera_forms_entry_meta_templates', array( $this, 'get_admin_meta_templates'),1);
60
 
61
  add_action( 'wp_loaded', array( $this, 'save_form') );
62
  add_action( 'media_buttons', array($this, 'shortcode_insert_button' ), 11 );
65
  add_action("wp_ajax_browse_entries", array( $this, 'browse_entries') );
66
  add_action("wp_ajax_save_cf_setting", array( $this, 'save_cf_setting') );
67
  add_action("wp_ajax_cf_dismiss_pointer", array( $this, 'update_pointer') );
68
+ add_action("wp_ajax_cf_bulk_action", array( $this, 'bulk_action') );
69
+
70
+ add_action( 'admin_footer', array( $this, 'add_shortcode_inserter'));
71
+
72
+ }
73
+
74
+
75
 
 
76
 
77
+ public function bulk_action(){
78
+
79
+ if(empty($_POST['do'])){
80
+ die;
81
+ }
82
+
83
+ switch ($_POST['do']) {
84
+ case 'active':
85
+ case 'trash':
86
+ case 'delete':
87
+ global $wpdb;
88
+
89
+ // clean out
90
+ $items = array();
91
+ $selectors = array();
92
+ foreach((array) $_POST['items'] as $item_id){
93
+ $items[] = (int) $item_id;
94
+ $selectors[] = '#entry_row_' . (int) $item_id;
95
+ }
96
+ switch ($_POST['do']) {
97
+ case 'delete':
98
+ $result = $wpdb->query( "DELETE FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `id` IN (".implode(',', $items).");" );
99
+ $result = $wpdb->query( "DELETE FROM `" . $wpdb->prefix . "cf_form_entry_values` WHERE `entry_id` IN (".implode(',', $items).");" );
100
+ $result = $wpdb->query( "DELETE FROM `" . $wpdb->prefix . "cf_form_entry_meta` WHERE `entry_id` IN (".implode(',', $items).");" );
101
+ header('Content-Type: application/json');
102
+ $out['status'] = 'reload';
103
+ echo json_encode($out);
104
+ break;
105
+
106
+ default:
107
+ $result = $wpdb->query( $wpdb->prepare( "UPDATE `" . $wpdb->prefix . "cf_form_entries` SET `status` = %s WHERE `id` IN (".implode(',', $items).");", $_POST['do'] ) );
108
+ break;
109
+ }
110
+
111
+ if( $result ){
112
+ header('Content-Type: application/json');
113
+ $out['status'] = $_POST['do'];
114
+ $out['undo'] = ( $_POST['do'] === 'trash' ? 'active' : 'trash' );
115
+ $out['undo_text'] = ( $_POST['do'] === 'trash' ? __('Restore') : __('Trash') );
116
+
117
+ $out['entries'] = implode(',',$selectors);
118
+ $out['total'] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(`id`) AS `total` FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `form_id` = %s && `status` = 'active';", $_POST['form']));
119
+ $out['trash'] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(`id`) AS `total` FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `form_id` = %s && `status` = 'trash';", $_POST['form']));
120
+ echo json_encode($out);
121
+ }
122
+ exit();
123
+
124
+ break;
125
+ case 'export':
126
+
127
+ $transientid = uniqid('cfe');
128
+ set_transient( $transientid, $_POST['items'], 180 );
129
+ header('Content-Type: application/json');
130
+ $out['url'] = "admin.php?page=caldera-forms&export=" . $_POST['form'] . "&tid=" . $transientid;
131
+ echo json_encode($out);
132
+ exit();
133
+ break;
134
+ default:
135
+ # code...
136
+ break;
137
+ }
138
+ exit();
139
  }
140
 
141
+
142
  public static function update_pointer(){
143
 
144
  if(!empty($_POST['pointer'])){
174
  public static function get_admin_templates(){
175
  include CFCORE_PATH . 'ui/admin_templates.php';
176
  }
177
+ public static function get_admin_meta_templates(){
178
+
179
+ $processors = apply_filters( 'caldera_forms_get_form_processors', array() );
180
+ if(!empty($processors)){
181
+ foreach($processors as $processor_type=>$processor_config){
182
+ if( isset( $processor_config['meta_template'] ) && file_exists( $processor_config['meta_template'] ) ){
183
+ echo "{{#if ".$processor_type."_template}}\r\n";
184
+ echo "{{#each data}}\r\n";
185
+ echo "{{#if title}}\r\n";
186
+ echo "<h4>{{title}}</h4>\r\n";
187
+ echo "{{/if}}\r\n";
188
+ echo "{{#each entry}}\r\n";
189
+ include $processor_config['meta_template'];
190
+ echo "{{/each}}\r\n";
191
+ echo "{{/each}}\r\n";
192
+ echo "{{/if}}\r\n";
193
+ }
194
+ }
195
+ }
196
+ }
197
 
198
  public static function get_entry_actions(){
199
 
212
  $viewer_buttons = 'data-modal-buttons=\'' . implode(';', $viewer_buttons) . '\'';
213
  }
214
 
215
+ echo '{{#if ../../is_active}}<button class="button button-small ajax-trigger view-entry-btn" data-active-class="none" data-load-class="spinner" ' . $viewer_buttons . ' data-group="viewentry" data-entry="{{_entry_id}}" data-form="{{../../form}}" data-action="get_entry" data-modal="view_entry" data-modal-width="600" data-modal-title="' . __('Entry', 'caldera-forms') . ' # {{_entry_id}}" data-template="#view-entry-tmpl" type="button">' . __('View', 'caldera-forms') . '</button> {{/if}}';
216
+ echo '<button type="button" class="button button-small ajax-trigger" data-load-class="active" data-panel="{{#if ../../is_trash}}trash{{/if}}{{#if ../../is_active}}active{{/if}}" data-do="{{#if ../../is_trash}}active{{/if}}{{#if ../../is_active}}trash{{/if}}" data-callback="cf_refresh_view" data-form="{{../../form}}" data-active-class="disabled" data-group="row{{_entry_id}}" data-load-element="#entry_row_{{_entry_id}}" data-action="cf_bulk_action" data-items="{{_entry_id}}">{{#if ../../is_trash}}' . __('Restore') . '{{/if}}{{#if ../../is_active}}' . __('Trash') . '{{/if}}</button>';
217
  }
218
 
219
  public static function set_viewer_buttons($buttons){
258
  }
259
 
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  public static function browse_entries(){
262
 
263
  global $wpdb;
272
  $selects = array();
273
 
274
  // get all fieldtype
275
+ $field_types = Caldera_Forms::get_field_types();
276
+
277
+
278
  $fields = array();
279
  if(!empty($form['fields'])){
280
  foreach($form['fields'] as $fid=>$field){
297
 
298
  $data = array();
299
 
300
+ $filter = null;
301
+ if(!empty($selects)){
302
+ //$filter .= " AND `value`.`slug` IN (" . implode(',', $selects) . ") ";
303
+ }
304
+ // status
305
+ $status = "'active'";
306
+ if(!empty($_POST['status'])){
307
+ $status = $wpdb->prepare("%s", $_POST['status']);
308
+ }
309
+
310
+
311
+ $data['trash'] = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(`id`) AS `total` FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `form_id` = %s AND `status` = 'trash';", $_POST['form']));
312
+ $data['active'] = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(`id`) AS `total` FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `form_id` = %s AND `status` = 'active';", $_POST['form']));
313
+
314
+
315
+ // set current total
316
+ if(!empty($_POST['status']) && isset($data[$_POST['status']])){
317
+ $data['total'] = $data[$_POST['status']];
318
+ }else{
319
+ $data['total'] = $data['active'];
320
+ }
321
+
322
 
323
  $data['pages'] = ceil($data['total'] / $perpage );
324
 
339
  $offset = ($page - 1) * $perpage;
340
  $limit = $offset . ',' . $perpage;
341
 
342
+ //if(!empty($selects)){
343
+ //$filter .= " AND `entry`.`status` = ".$status." ";
344
+ //}
345
+
346
+
347
  $rawdata = $wpdb->get_results($wpdb->prepare("
348
  SELECT
349
+ `id`,
350
+ `form_id`
351
  FROM `" . $wpdb->prefix ."cf_form_entries`
352
 
353
+ WHERE `form_id` = %s AND `status` = ".$status." ORDER BY `datestamp` DESC LIMIT " . $limit . ";", $_POST['form'] ));
354
 
355
  if(!empty($rawdata)){
356
 
357
+ foreach($rawdata as $entry){
358
+ //$data = Caldera_Forms::get_submission_data($entry->form_id, $entry->id);
359
+ }
360
+
361
  $ids = array();
362
  foreach($rawdata as $row){
363
  $ids[] = $row->id;
364
  }
365
 
 
 
 
 
366
  $rawdata = $wpdb->get_results("
367
  SELECT
368
  `entry`.`id` as `_entryid`,
383
  $dateformat = get_option('date_format');
384
  $timeformat = get_option('time_format');
385
  foreach($rawdata as $row){
 
386
  if(!empty($row->_user_id)){
387
  $user = get_userdata( $row->_user_id );
388
+ if(!empty($user)){
389
+ $data['entries']['E' . $row->_entryid]['user']['ID'] = $user->ID;
390
+ $data['entries']['E' . $row->_entryid]['user']['name'] = $user->data->display_name;
391
+ $data['entries']['E' . $row->_entryid]['user']['email'] = $user->data->user_email;
392
+ $data['entries']['E' . $row->_entryid]['user']['avatar'] = get_avatar( $user->ID, 64 );
393
+ }
394
  }
395
  $data['entries']['E' . $row->_entryid]['_entry_id'] = $row->_entryid;
396
  $data['entries']['E' . $row->_entryid]['_date'] = date_i18n( $dateformat.' '.$timeformat, strtotime($row->_date_submitted), $gmt_offset);
397
+
398
  // setup default data array
399
  if(!isset($data['entries']['E' . $row->_entryid]['data'])){
400
  if(isset($field_labels)){
405
  }
406
  }
407
 
408
+ if(!empty($field_labels[$row->slug])){
409
+
410
+ $label = $field_labels[$row->slug];
411
 
412
  // check view handler
413
  $field = $fields[$row->slug];
414
 
415
+ $row->value = apply_filters('caldera_forms_view_field_' . $field['type'], $row->value, $field, $form);
 
 
 
 
 
 
 
 
 
 
416
 
417
 
418
  if(isset($data['entries']['E' . $row->_entryid]['data'][$row->slug])){
426
  $data['entries']['E' . $row->_entryid]['data'][$row->slug] = $row->value;
427
  }
428
  }
429
+
430
  }
431
  }
432
  }
433
 
434
+ // set status output
435
+ $data['is_' . $_POST['status']] = true;
436
+
437
  header('Content-Type: application/json');
438
  echo json_encode( $data );
439
  exit;
511
  wp_enqueue_script( 'jquery-ui-droppable' );
512
 
513
  }
514
+ if(!empty($_GET['edit-entry'])){
515
+ wp_enqueue_style( 'cf-grid-styles', CFCORE_URL . 'assets/css/caldera-grid.css', array(), self::VERSION );
516
+ }
517
+
518
+
519
  // Load Field Types Styles & Scripts
520
  $field_types = apply_filters('caldera_forms_get_field_types', array() );
521
 
522
+ // load panels
523
  $panel_extensions = apply_filters('caldera_forms_get_panel_extensions', array() );
524
 
525
+ // load processors
526
+ $form_processors = apply_filters('caldera_forms_get_form_processors', array() );
527
+
528
  // merge a list
529
+ $merged_types = array_merge($field_types, $panel_extensions, $form_processors);
530
 
531
  foreach( $merged_types as $type=>&$config){
532
 
622
  echo "<form method=\"POST\" action=\"admin.php?page=" . $this->plugin_slug . "\" data-load-element=\"#save_indicator\" data-sender=\"ajax\" class=\"caldera-forms-options-form edit-update-trigger\">\r\n";
623
  include CFCORE_PATH . 'ui/edit.php';
624
  echo "</form>\r\n";
625
+ }elseif(!empty($_GET['edit-entry'])){
626
+ include CFCORE_PATH . 'ui/edit-entry.php';
627
  }else{
628
  include CFCORE_PATH . 'ui/admin.php';
629
  }
661
  }
662
 
663
  }
664
+ if( isset($_POST['cfimporter']) ){
665
+
666
+ if ( check_admin_referer( 'cf-import', 'cfimporter' ) ) {
667
+ if(!empty($_FILES['import_file']['size'])){
668
+ $loc = wp_upload_dir();
669
+ if(move_uploaded_file($_FILES['import_file']['tmp_name'], $loc['path'].'/cf-form-import.json')){
670
+ $data = json_decode(file_get_contents($loc['path'].'/cf-form-import.json'), true);
671
+ if(isset($data['ID']) && isset($data['name']) && isset($data['fields'])){
672
+
673
+ // get form registry
674
+ $forms = get_option( '_caldera_forms' );
675
+ if(empty($forms)){
676
+ $forms = array();
677
+ }
678
+
679
+ // add form to registry
680
+ $forms[$data['ID']] = $data;
681
+
682
+ // remove undeeded settings for registry
683
+ if(isset($forms[$data['ID']]['layout_grid'])){
684
+ unset($forms[$data['ID']]['layout_grid']);
685
+ }
686
+ if(isset($forms[$data['ID']]['fields'])){
687
+ unset($forms[$data['ID']]['fields']);
688
+ }
689
+ if(isset($forms[$data['ID']]['processors'])){
690
+ unset($forms[$data['ID']]['processors']);
691
+ }
692
+ if(isset($forms[$data['ID']]['settings'])){
693
+ unset($forms[$data['ID']]['settings']);
694
+ }
695
+
696
+ // add from to list
697
+ update_option($data['ID'], $data);
698
+ do_action('caldera_forms_import_form', $data);
699
+
700
+ update_option( '_caldera_forms', $forms );
701
+ do_action('caldera_forms_save_form_register', $data);
702
+
703
+ wp_redirect( 'admin.php?page=caldera-forms&edit=' . $data['ID'] );
704
+ exit;
705
+
706
+ }else{
707
+ wp_die( __('Sorry, File is not valid.', 'caldera-forms'), __('Form Import Error', 'caldera-forms') );
708
+ }
709
+ }
710
+ }else{
711
+ wp_die( __('Sorry, File not uploaded.', 'caldera-forms'), __('Form Import Error', 'caldera-forms') );
712
+ }
713
+
714
+ }else{
715
+
716
+ wp_die( __('Sorry, please try again', 'caldera-forms'), __('Form Import Error', 'caldera-forms') );
717
+ }
718
+
719
+ }
720
+ if(!empty($_GET['export-form'])){
721
+
722
+ $form = get_option( $_GET['export-form'] );
723
+
724
+ if(empty($form)){
725
+ wp_die( __('Form does not exist.') );
726
+ }
727
+
728
+ header("Pragma: public");
729
+ header("Expires: 0");
730
+ header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
731
+ header("Cache-Control: private",false);
732
+ header("Content-Type: application/json");
733
+ header("Content-Disposition: attachment; filename=\"" . sanitize_file_name( strtolower( $form['name'] ) ) . "-export.json\";" );
734
+ echo json_encode($form);
735
+ exit;
736
 
737
+ }
738
  if(!empty($_GET['export'])){
739
 
740
  $form = get_option( $_GET['export'] );
748
  $labels[$field['slug']] = $field['label'];
749
  }
750
  }
751
+ $filter = null;
752
+ // export set - transient
753
+ if(!empty($_GET['tid'])){
754
+ $items = get_transient( $_GET['tid'] );
755
+ if(!empty($items)){
756
+ $filter = ' AND `entry`.`id` IN (' . implode(',', $items) . ') ';
757
+ }else{
758
+ wp_die( __('Export selection has expired', 'caldera-forms') , __('Export Expired', 'caldera-forms') );
759
+ }
760
+ }
761
 
762
  $rawdata = $wpdb->get_results($wpdb->prepare("
763
  SELECT
771
  LEFT JOIN `" . $wpdb->prefix ."cf_form_entry_values` AS `value` ON (`entry`.`id` = `value`.`entry_id`)
772
 
773
  WHERE `entry`.`form_id` = %s
774
+ " . $filter . "
775
  ORDER BY `entry`.`datestamp` DESC;", $_GET['export']));
776
 
777
  $data = array();
832
  }
833
 
834
  if( isset($_POST['config']) && isset( $_POST['cf_edit_nonce'] ) ){
835
+
836
  // if this fails, check_admin_referer() will automatically print a "failed" page and die.
837
  if ( check_admin_referer( 'cf_edit_element', 'cf_edit_nonce' ) ) {
838
+
839
  // strip slashes
840
+ $data = json_decode( stripslashes_deep($_POST['config']) , ARRAY_A );
 
841
  // get form registry
842
  $forms = get_option( '_caldera_forms' );
843
  if(empty($forms)){
844
  $forms = array();
845
  }
846
+ // option value labels
847
+ if(!empty($data['fields'])){
848
+ foreach($data['fields'] as &$field){
849
+ if(!empty($field['config']['option']) && is_array($field['config']['option'])){
850
+ foreach($field['config']['option'] as &$option){
851
+ if(!isset($option['value'])){
852
+ $option['value'] = $option['label'];
853
+ }
854
+ }
855
+ }
856
+ }
857
+ }
858
+
859
  // add form to registry
860
  $forms[$data['ID']] = $data;
861
 
873
  unset($forms[$data['ID']]['settings']);
874
  }
875
 
876
+ // combine structure pages
877
+ $data['layout_grid']['structure'] = implode('#', $data['layout_grid']['structure']);
878
+
879
  // add from to list
880
  update_option($data['ID'], $data);
881
  do_action('caldera_forms_save_form', $data);
965
  "canvas" => $path . "layout.php",
966
  "side_panel" => $path . "layout_side.php",
967
  ),
968
+ "pages" => array(
969
+ "name" => __("Pages", 'caldera-forms'),
970
+ "location" => "lower",
971
+ "label" => __("Form Pages", 'caldera-forms'),
972
+ "canvas" => $path . "pages.php",
973
+ ),
974
  "processors" => array(
975
  "name" => __("Processors", 'caldera-forms'),
976
  "location" => "lower",
classes/caldera-grid.php CHANGED
@@ -9,234 +9,245 @@ if( !class_exists( 'Caldera_Form_Grid' )){
9
 
10
  class Caldera_Form_Grid {
11
 
12
- private $layoutString = array();
13
- private $debug = false;
14
- private $layoutType = false;
15
- private $config = array();
16
- private $nests = array();
17
- private $output = '';
18
- public $grid = array();
19
-
 
20
 
21
- function __construct($config) {
22
-
23
- $this->config = $config;//json_decode(file_get_contents(plugin_dir_path(__FILE__) . '/engine-config.json'), true);
24
- if(empty($this->config)){
25
- echo 'Error loading engine config';
26
- die;
27
- }
28
- }
29
- public function debug(){
30
- $this->debug = true;
31
- }
32
- public function setLayout($str){
33
- // find nests
34
- preg_match_all("/\[[0-9:\|]+\]/", $str, $matches);
35
- if(!empty($matches[0])){
36
- foreach($matches[0] as $key=>$nest){
37
- $port = uniqid('__');
38
- $this->nests[$port] = substr($nest, 1, strlen($nest)-2);
39
- $str = str_replace($nest, $port, $str);
40
- }
41
- }
42
- $this->grid = $this->splitString($str);
43
- }
44
- private function splitString($str){
45
- $rows = explode('|', $str);
46
- $grid = array();
47
- foreach($rows as $row=>$cols){
48
- $cols = explode(':',$cols);
49
- foreach($cols as $col=>$span){
50
- $nest = strpos($span, '__');
51
- if($nest !== false){
52
- $grid[$row+1][$col+1] = $this->splitString($this->nests[substr($span,$nest)]);
53
- }
54
- $grid[$row+1][$col+1]['span'] = $span;
55
- $grid[$row+1][$col+1]['html'] = '';
56
- }
57
- }
58
- return $grid;
59
- }
60
- static function mergeArray($first, $second, $type = 'replace'){
61
- foreach($second as $key => $value) {
62
- if(is_array($value)){
63
- if(!isset($first[$key])){
64
- $first[$key] = array();
65
- }
66
- $first[$key] = self::mergeArray($first[$key], $value, $type);
67
- }else{
68
- switch ($type){
69
- case 'replace':
70
- $first[$key] = $value;
71
- break;
72
- case 'append':
73
- if(empty($first[$key])){
74
- $first[$key] = $value;
75
- }else{
76
- $first[$key] .= $value;
77
- }
78
- break;
79
- case 'prepend':
80
- if(empty($first[$key])){
81
- $first[$key] = $value;
82
- }else{
83
- $first[$key] = $value.$first[$key];
84
- }
85
- $first[$key] = $value.$first[$key];
86
- break;
87
- }
88
- }
89
- }
90
- return $first;
91
- }
92
- static function mapValue($type, $value, &$map){
93
- $out = '';$end = '';
94
- $map = explode(':', $map);
95
- foreach($map as $key=>$val){
96
- $out .= '{"'.$val.'":';
97
- $end .= "}";
98
- }
99
- $map = json_decode($out.json_encode(array($type=>$value)).$end, true);
100
- }
101
- public function html($html, $map, $type = 'replace') {
102
- $this->mapValue('html', $html, $map);
103
- $this->grid = self::mergeArray($this->grid, $map, $type);
104
- }
105
- public function before($html, $map) {
106
- $this->mapValue('before', $html, $map);
107
- $this->grid = self::mergeArray($this->grid, $map);
108
- }
109
- public function after($html, $map) {
110
- $this->mapValue('after', $html, $map);
111
- $this->grid = self::mergeArray($this->grid, $map);
112
- }
113
- public function append($html, $map) {
114
- self::html($html, $map, 'append');
115
- }
116
- public function prepend($html, $map) {
117
- self::html($html, $map, 'prepend');
118
- }
119
- public function setClass($class, $map){
120
- $this->mapValue('class', $class, $map);
121
- $this->grid = self::mergeArray($this->grid, $map);
122
- }
123
- public function appendClass($class, $map){
124
- $this->mapValue('class', $class, $map);
125
- $this->grid = self::mergeArray($this->grid, $map, 'append');
126
- }
127
- public function prependClass($class, $map){
128
- $this->mapValue('class', $class, $map);
129
- $this->grid = self::mergeArray($this->grid, $map, 'prepend');
130
- }
131
- public function setRowID($ID, $row){
132
- if(!isset($this->grid[$row])){return;}
133
- $this->grid[$row]['id'] = $ID;
134
- }
135
- public function setID($ID, $map){
136
- $this->mapValue('id', $ID, $map);
137
- $this->grid = self::mergeArray($this->grid, $map);
138
- }
139
- public function renderLayout($grid = false) {
140
- $inner = true;
141
- if(empty($this->grid)){
142
- return 'ERROR: Layout string not set.';
143
- }
144
- if(empty($grid)){
145
- $inner = false;
146
- $grid = $this->grid;
147
- }
148
-
149
- foreach($grid as $row=>$cols){
150
 
151
- $rowID = '';
152
- $rowClass = '';
153
- $rowBefore = '';
154
- $rowAfter = '';
155
-
156
- if(isset($cols['id'])){
157
- $rowID = 'id="'.$cols['id'].'" ';
158
- unset($cols['id']);
159
- }
160
-
161
- if(isset($cols['class'])){
162
- $rowClass = $cols['class'];
163
- unset($cols['class']);
164
- }
165
-
166
- if(isset($grid['*']['class'])){
167
- $rowClass .= $grid['*']['class'];
168
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- if($row === 1 && $row !== count($grid)){
171
- $rowClass .= " ".$this->config['first'];
172
- }elseif ($row === count($grid) && $row !== 1){
173
- $rowClass .= " ".$this->config['last'];
174
- }elseif ($row === count($grid) && $row === 1){
175
- $rowClass .= " ".$this->config['single'];
176
- }
177
-
178
- if(isset($cols['before'])){
179
- $this->output .= $cols['before'];
180
- }
181
-
182
- $this->output .= sprintf($this->config['before'], $rowID, $rowClass);//"<div ".$rowID."class=\"".$gridClass." ".$rowClass."\">\n";
183
-
184
- if(!is_array($cols)){
185
- echo $cols;
186
- }
187
- foreach($cols as $col=>$content){
188
- if(!isset($content['span'])){continue;}
189
- $colClass = '';
190
- if(isset($content['class'])){
191
- $colClass = $content['class'];
192
- unset($content['class']);
193
- }
194
- if(isset($cols['*']['class'])){
195
- $colClass .= $cols['*']['class'];
196
- }
197
-
198
- if($col === 1 && $col !== count($cols)){
199
- $colClass .= " ".$this->config['column_first'];
200
- }elseif($col === count($cols) && $col !== 1){
201
- $colClass .= " ".$this->config['column_last'];
202
- }elseif($col === count($cols) && $col === 1){
203
- $colClass .= " ".$this->config['column_single'];
204
- }
205
- $colID = '';
206
- if(isset($content['id'])){
207
- $colID = 'id="'.$content['id'].'"';
208
- unset($content['id']);
209
- }
210
- if(isset($content['before'])){
211
- $this->output .= $content['before'];
212
- unset($content['before']);
213
- }
214
- $afterBuffer = '';
215
- if(isset($content['after'])){
216
- $afterBuffer = $content['after'];
217
- unset($content['after']);
218
- }
219
- //$span = !empty($this->config['column_content['span']]) ? $content['span'] : 'default';
220
- $this->output .= sprintf($this->config['column_before'], $colID, $content['span'], $colClass);//" <div class=\"span".$content['span']." ".$colClass."\">\n";
221
- $this->output .= $content['html'];
222
- unset($content['html']);
223
- unset($content['span']);
224
- if(!empty($content)){
225
- $this->output = $this->renderLayout($content);
226
- }
227
- $this->output .= $this->config['column_after'];
228
- $this->output .= $afterBuffer;
229
- }
230
- $this->output .= $this->config['after'];//"</div>\n";
231
- if(isset($cols['after'])){
232
- $this->output .= $cols['after'];
233
- }
234
-
235
- }
236
 
237
- //dump($grid);
238
- return $this->output;
239
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
  }
242
  }
9
 
10
  class Caldera_Form_Grid {
11
 
12
+ private $layoutString = array();
13
+ private $debug = false;
14
+ private $layoutType = false;
15
+ private $config = array();
16
+ private $nests = array();
17
+ private $output = '';
18
+ private $paged = false;
19
+ public $grid = array();
20
+
21
 
22
+ function __construct($config) {
23
+
24
+ $this->config = $config;//json_decode(file_get_contents(plugin_dir_path(__FILE__) . '/engine-config.json'), true);
25
+ if(empty($this->config)){
26
+ echo 'Error loading engine config';
27
+ die;
28
+ }
29
+ }
30
+ public function debug(){
31
+ $this->debug = true;
32
+ }
33
+ public function setLayout($str){
34
+ // find pages
35
+ if( false !== strpos($str, '#') ){
36
+ $this->paged = true;
37
+ }
38
+ // find nests
39
+ preg_match_all("/\[[0-9:\|]+\]/", $str, $matches);
40
+ if(!empty($matches[0])){
41
+ foreach($matches[0] as $key=>$nest){
42
+ $port = uniqid('__');
43
+ $this->nests[$port] = substr($nest, 1, strlen($nest)-2);
44
+ $str = str_replace($nest, $port, $str);
45
+ }
46
+ }
47
+ $this->grid = $this->splitString($str);
48
+ }
49
+ private function splitString($str){
50
+
51
+ $rows = explode('|', $str);
52
+ $grid = array();
53
+ foreach($rows as $row=>$cols){
54
+ $cols = explode(':',$cols);
55
+ foreach($cols as $col=>$span){
56
+ $nest = strpos($span, '__');
57
+ if($nest !== false){
58
+ $grid[$row+1][$col+1] = $this->splitString($this->nests[substr($span,$nest)]);
59
+ }
60
+ $grid[$row+1][$col+1]['span'] = $span;
61
+ $grid[$row+1][$col+1]['html'] = '';
62
+ }
63
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
+ return $grid;
66
+ }
67
+ static function mergeArray($first, $second, $type = 'replace'){
68
+ foreach($second as $key => $value) {
69
+ if(is_array($value)){
70
+ if(!isset($first[$key])){
71
+ $first[$key] = array();
72
+ }
73
+ $first[$key] = self::mergeArray($first[$key], $value, $type);
74
+ }else{
75
+ switch ($type){
76
+ case 'replace':
77
+ $first[$key] = $value;
78
+ break;
79
+ case 'append':
80
+ if(empty($first[$key])){
81
+ $first[$key] = $value;
82
+ }else{
83
+ $first[$key] .= $value;
84
+ }
85
+ break;
86
+ case 'prepend':
87
+ if(empty($first[$key])){
88
+ $first[$key] = $value;
89
+ }else{
90
+ $first[$key] = $value.$first[$key];
91
+ }
92
+ $first[$key] = $value.$first[$key];
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ return $first;
98
+ }
99
+ static function mapValue($type, $value, &$map){
100
+ $out = '';$end = '';
101
+ $map = explode(':', $map);
102
+ foreach($map as $key=>$val){
103
+ $out .= '{"'.$val.'":';
104
+ $end .= "}";
105
+ }
106
+ $map = json_decode($out.json_encode(array($type=>$value)).$end, true);
107
+ }
108
+ public function html($html, $map, $type = 'replace') {
109
+ $this->mapValue('html', $html, $map);
110
+ $this->grid = self::mergeArray($this->grid, $map, $type);
111
+ }
112
+ public function before($html, $map, $type = 'replace') {
113
+ $this->mapValue('before', $html, $map);
114
+ $this->grid = self::mergeArray($this->grid, $map, $type);
115
+ }
116
+ public function after($html, $map, $type = 'replace') {
117
+ $this->mapValue('after', $html, $map);
118
+ $this->grid = self::mergeArray($this->grid, $map, $type);
119
+ }
120
+ public function append($html, $map) {
121
+ self::html($html, $map, 'append');
122
+ }
123
+ public function prepend($html, $map) {
124
+ self::html($html, $map, 'prepend');
125
+ }
126
+ public function setClass($class, $map){
127
+ $this->mapValue('class', $class, $map);
128
+ $this->grid = self::mergeArray($this->grid, $map);
129
+ }
130
+ public function appendClass($class, $map){
131
+ $this->mapValue('class', $class, $map);
132
+ $this->grid = self::mergeArray($this->grid, $map, 'append');
133
+ }
134
+ public function prependClass($class, $map){
135
+ $this->mapValue('class', $class, $map);
136
+ $this->grid = self::mergeArray($this->grid, $map, 'prepend');
137
+ }
138
+ public function setRowID($ID, $row){
139
+ if(!isset($this->grid[$row])){return;}
140
+ $this->grid[$row]['id'] = $ID;
141
+ }
142
+ public function setID($ID, $map){
143
+ $this->mapValue('id', $ID, $map);
144
+ $this->grid = self::mergeArray($this->grid, $map);
145
+ }
146
+ public function renderLayout($grid = false) {
147
+ $inner = true;
148
+ if(empty($this->grid)){
149
+ return 'ERROR: Layout string not set.';
150
+ }
151
+ if(empty($grid)){
152
+ $inner = false;
153
+ $grid = $this->grid;
154
+ }
155
+
156
+ foreach($grid as $row=>$cols){
157
 
158
+ $rowID = '';
159
+ $rowClass = '';
160
+ $rowBefore = '';
161
+ $rowAfter = '';
162
+
163
+ if(isset($cols['id'])){
164
+ $rowID = 'id="'.$cols['id'].'" ';
165
+ unset($cols['id']);
166
+ }
167
+
168
+ if(isset($cols['class'])){
169
+ $rowClass = $cols['class'];
170
+ unset($cols['class']);
171
+ }
172
+
173
+ if(isset($grid['*']['class'])){
174
+ $rowClass .= $grid['*']['class'];
175
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
+ if($row === 1 && $row !== count($grid)){
178
+ $rowClass .= " ".$this->config['first'];
179
+ }elseif ($row === count($grid) && $row !== 1){
180
+ $rowClass .= " ".$this->config['last'];
181
+ }elseif ($row === count($grid) && $row === 1){
182
+ $rowClass .= " ".$this->config['single'];
183
+ }
184
+
185
+ if(isset($cols['before'])){
186
+ $this->output .= $cols['before'];
187
+ unset($cols['before']);
188
+ }
189
+
190
+ $this->output .= sprintf($this->config['before'], $rowID, $rowClass);//"<div ".$rowID."class=\"".$gridClass." ".$rowClass."\">\n";
191
+
192
+ if(!is_array($cols)){
193
+ echo $cols;
194
+ }else{
195
+ foreach($cols as $col=>$content){
196
+ if(!is_array($content) || empty($content)){
197
+ continue;
198
+ }
199
+ if(!isset($content['span'])){continue;}
200
+ $colClass = '';
201
+ if(isset($content['class'])){
202
+ $colClass = $content['class'];
203
+ unset($content['class']);
204
+ }
205
+ if(isset($cols['*']['class'])){
206
+ $colClass .= $cols['*']['class'];
207
+ }
208
+
209
+ if($col === 1 && $col !== count($cols)){
210
+ $colClass .= " ".$this->config['column_first'];
211
+ }elseif($col === count($cols) && $col !== 1){
212
+ $colClass .= " ".$this->config['column_last'];
213
+ }elseif($col === count($cols) && $col === 1){
214
+ $colClass .= " ".$this->config['column_single'];
215
+ }
216
+ $colID = '';
217
+ if(isset($content['id'])){
218
+ $colID = 'id="'.$content['id'].'"';
219
+ unset($content['id']);
220
+ }
221
+ if(isset($content['before'])){
222
+ $this->output .= $content['before'];
223
+ unset($content['before']);
224
+ }
225
+ $afterBuffer = '';
226
+ if(isset($content['after'])){
227
+ $afterBuffer = $content['after'];
228
+ unset($content['after']);
229
+ }
230
+ //$span = !empty($this->config['column_content['span']]) ? $content['span'] : 'default';
231
+ $this->output .= sprintf($this->config['column_before'], $colID, $content['span'], $colClass);//" <div class=\"span".$content['span']." ".$colClass."\">\n";
232
+ $this->output .= $content['html'];
233
+ unset($content['html']);
234
+ unset($content['span']);
235
+ if(!empty($content)){
236
+ $this->output = $this->renderLayout($content);
237
+ }
238
+ $this->output .= $this->config['column_after'];
239
+ $this->output .= $afterBuffer;
240
+ }
241
+ }
242
+ $this->output .= $this->config['after'];//"</div>\n";
243
+ if(isset($cols['after'])){
244
+ $this->output .= $cols['after'];
245
+ }
246
+
247
+ }
248
+
249
+ return $this->output;
250
+ }
251
 
252
  }
253
  }
classes/core.php CHANGED
@@ -44,16 +44,19 @@ class Caldera_Forms {
44
 
45
 
46
  // add element & fields filters
47
- add_filter('caldera_forms_get_field_types', array( $this, 'get_field_types'));
48
  add_filter('caldera_forms_get_form_processors', array( $this, 'get_form_processors'));
49
  add_filter('caldera_forms_submit_redirect_complete', array( $this, 'do_redirect'),10, 4);
50
-
 
 
 
51
  // mailser
 
52
  add_filter('caldera_forms_mailer', array( $this, 'mail_attachment_check'),10, 3);
53
 
54
  // action
55
- add_action('caldera_forms_submit_complete', array( $this, 'save_final_form'),1,2);
56
-
57
 
58
  add_action("wp_ajax_get_entry", array( $this, 'get_entry') );
59
  // find if profile is loaded
@@ -62,6 +65,15 @@ class Caldera_Forms {
62
  // render shortcode
63
  add_shortcode( 'caldera_form', array( $this, 'render_form') );
64
 
 
 
 
 
 
 
 
 
 
65
  }
66
 
67
 
@@ -77,42 +89,131 @@ class Caldera_Forms {
77
  load_textdomain( $domain, trailingslashit( WP_LANG_DIR ) . $domain . '/' . $domain . '-' . $locale . '.mo' );
78
  load_plugin_textdomain( $domain, FALSE, basename( dirname( __FILE__ ) ) . '/languages' );
79
  }
80
-
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
- public static function handle_file_upload($value, $field, $data, $form){
84
 
85
- if(!empty($_FILES[$field['slug']]['size'])){
86
- // check is allowed
87
- if(!empty($field['config']['allowed'])){
88
- $types = explode(',',$field['config']['allowed']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
- foreach($types as &$type){
91
- $type=trim($type);
92
- }
93
- $check = pathinfo($_FILES[$field['slug']]['name']);
94
- if(!in_array( $check['extension'], $types)){
95
- if(count($types) > 1){
96
- return array('_fail'=>__('File type not allowed. Allowed types are: ', 'caldera-forms') . ' '. implode(', ', $types) );
97
- }else{
98
- return array('_fail'=>__('File type needs to be', 'caldera-forms') . ' .' . $types[0] );
99
  }
100
  }
101
-
102
  }
 
 
 
 
 
 
 
 
 
103
 
 
104
 
105
- $upload = wp_upload_bits( $_FILES[$field['slug']]['name'], null, file_get_contents($_FILES[$field['slug']]['tmp_name']) );
106
 
107
- if(empty($upload['error'])){
108
- return $upload['url'];
109
- }else{
110
- return array('_fail'=>$upload['error']);
 
 
 
 
 
 
111
  }
112
  }
113
- return null;
114
- }
115
 
 
 
116
 
117
  public static function handle_file_view($value, $field, $form){
118
 
@@ -123,12 +224,11 @@ class Caldera_Forms {
123
  public static function mail_attachment_check($mail, $data, $form){
124
 
125
  // check for
126
- foreach($form['fields'] as $field){
127
  if($field['type'] == 'file' && isset($field['config']['attach'])){
128
 
129
-
130
  $dir = wp_upload_dir();
131
- $file = str_replace($dir['baseurl'], $dir['basedir'], $data[$field['slug']]);
132
  if(file_exists($file)){
133
  $mail['attachments'][] = $file;
134
  }
@@ -139,14 +239,14 @@ class Caldera_Forms {
139
  }
140
 
141
 
142
- public static function captcha_check($value, $field, $data, $form){
143
-
144
- if(empty($data['recaptcha_response_field'])){
145
  return array('_fail' => __("The reCAPTCHA field is required.", 'caldera-forms'));
146
  }
147
  include_once CFCORE_PATH . 'fields/recaptcha/recaptchalib.php';
148
 
149
- $resp = recaptcha_check_answer ($field['config']['private_key'], $_SERVER["REMOTE_ADDR"], $data['recaptcha_challenge_field'], $data['recaptcha_response_field']);
150
 
151
  if (!$resp->is_valid) {
152
  return array('_fail' => __("The reCAPTCHA wasn't entered correctly.", 'caldera-forms'));
@@ -154,51 +254,190 @@ class Caldera_Forms {
154
  return true;
155
  }
156
 
 
 
157
 
 
158
 
159
- public static function save_final_form($data, $form){
160
- if(!empty($form['db_support'])){
 
161
 
162
- global $wpdb;
 
 
 
 
 
 
 
 
163
 
164
- $new_entry = array(
165
- 'form_id' => $form['ID'],
166
- 'user_id' => get_current_user_id(),
167
- 'datestamp' => date_i18n( 'Y-m-d H:i:s', time(), 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  );
169
- $wpdb->insert($wpdb->prefix . 'cf_form_entries', $new_entry);
170
- $entryid = $wpdb->insert_id;
 
 
 
 
 
 
 
 
 
171
 
172
- foreach($data as $field=>$values){
173
- if(is_array($values)){
174
- $keys = array_keys($values);
175
- if(is_int($keys[0])){
176
- foreach((array) $values as $value){
177
- /// repeatable numerik index has same key
178
- $field_item = array(
179
- 'entry_id' => $entryid,
180
- 'slug' => $field,
181
- 'value' => $value
182
- );
183
- $wpdb->insert($wpdb->prefix . 'cf_form_entry_values', $field_item);
184
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  }else{
186
- // named index is array stored
187
- $field_item = array(
188
- 'entry_id' => $entryid,
189
- 'slug' => $field,
190
- 'value' => json_encode( $values )
191
- );
192
- $wpdb->insert($wpdb->prefix . 'cf_form_entry_values', $field_item);
193
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  }else{
195
- $field_item = array(
196
- 'entry_id' => $entryid,
197
- 'slug' => $field,
198
- 'value' => $values
199
- );
200
- $wpdb->insert($wpdb->prefix . 'cf_form_entry_values', $field_item);
 
 
 
 
 
 
201
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  }
203
 
204
  }
@@ -211,46 +450,125 @@ class Caldera_Forms {
211
  $sendername = __('Caldera Forms Notification', 'caldera-forms');
212
  if(!empty($form['mailer']['sender_name'])){
213
  $sendername = $form['mailer']['sender_name'];
 
 
 
 
 
 
214
  }
215
  if(empty($form['mailer']['sender_email'])){
216
  $sendermail = get_option( 'admin_email' );
217
  }else{
218
  $sendermail = $form['mailer']['sender_email'];
 
 
 
 
 
 
 
 
 
 
219
  }
220
 
221
  $mail = array(
222
  'recipients' => array(),
223
- 'subject' => $form['mailer']['email_subject'],
224
  'message' => $form['mailer']['email_message']."\r\n",
225
  'headers' => array(
226
- 'From: ' . $sendername . ' <' . $sendermail . '>'
227
  ),
228
  'attachments' => array()
229
  );
230
 
 
 
 
231
  if($form['mailer']['email_type'] == 'html'){
232
  $mail['headers'][] = "Content-type: text/html";
 
233
  }
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  if(!empty($form['mailer']['recipients'])){
236
  $mail['recipients'] = explode(',', $form['mailer']['recipients']);
237
  }else{
238
  $mail['recipients'][] = get_option( 'admin_email' );
239
  }
240
 
 
 
241
  $submission = array();
242
- foreach ($data as $key=>$row) {
 
 
 
 
 
 
243
  if(is_array($row)){
244
  $keys = array_keys($row);
245
  if(is_int($keys[0])){
246
  $row = implode(', ', $row);
247
  }else{
248
  $tmp = array();
249
- foreach($row as $key=>$item){
250
  if(is_array($item)){
251
  $item = '( ' . implode(', ', $item).' )';
252
  }
253
- $tmp[] = $key.': '.$item;
254
  }
255
  $row = implode(', ', $tmp);
256
  }
@@ -258,13 +576,15 @@ class Caldera_Forms {
258
  $mail['message'] = str_replace('%'.$key.'%', $row, $mail['message']);
259
  $mail['subject'] = str_replace('%'.$key.'%', $row, $mail['subject']);
260
 
261
- $submission[] = $row;
 
262
  }
 
263
  // CSV
264
  if(!empty($form['mailer']['csv_data'])){
265
  ob_start();
266
  $df = fopen("php://output", 'w');
267
- fputcsv($df, array_keys($data));
268
  fputcsv($df, $submission);
269
  fclose($df);
270
  $csv = ob_get_clean();
@@ -272,22 +592,25 @@ class Caldera_Forms {
272
  $mail['attachments'][] = $csvfile['file'];
273
  }
274
 
275
- $mail = apply_filters( 'caldera_forms_mailer', $mail, $data, $form);
276
-
277
  if(empty($mail)){
278
  return;
279
  }
280
- // recipients
 
 
 
281
  foreach($mail['recipients'] as &$recipient){
282
  // trim spaces
283
  $recipient = trim($recipient);
284
  }
285
  $recipients = implode(',', $mail['recipients']);
 
286
  $headers = implode("\r\n", $mail['headers']);
287
 
288
  do_action( 'caldera_forms_do_mailer', $mail, $data, $form);
289
  if(!empty($mail)){
290
- if(wp_mail($recipients, $mail['subject'], $mail['message'], $headers, $mail['attachments'] )){
 
291
  // kill attachment.
292
  if(!empty($csvfile['file'])){
293
  if(file_exists($csvfile['file'])){
@@ -323,13 +646,13 @@ class Caldera_Forms {
323
 
324
 
325
 
326
- public static function do_redirect($referrer, $data, $form, $processid){
327
  if(isset($form['processors'])){
328
  foreach($form['processors'] as $processor){
329
  if($processor['type'] == 'form_redirect'){
330
 
331
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
332
- if(!self::check_condition($processor['conditions'], $data, $form)){
333
  continue;
334
  }
335
  }
@@ -343,37 +666,57 @@ class Caldera_Forms {
343
  return $referrer;
344
  }
345
 
346
- public static function send_auto_response($data, $config, $original_data){
347
-
348
- $headers = 'From: ' . $config['sender_name'] . ' <' . $config['sender_email'] . '>' . "\r\n";
349
- //$headers .= "Content-type: text/html\r\n";
 
350
 
351
  $message = $config['message'];
352
- foreach ($config as $key => $value) {
353
- if($key == 'message'){
354
- continue;
355
- }
356
- if(isset($data[$value])){
357
- $value = $data[$value];
358
- }else{
359
- $value = null;
360
  }
361
- $message = str_replace('%'.$key.'%', $value, $message);
362
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
 
364
- foreach ($data as $key => $value) {
365
- if($key == 'message'){
366
- continue;
367
- }
368
- if(is_array($value)){
369
- $value = implode(', ', $value);
370
  }
371
- $message = str_replace('%'.$key.'%', $value, $message);
372
  }
 
373
 
374
- wp_mail($data[$config['recipient_name']].' <'.$data[$config['recipient_email']].'>', $config['subject'], $message, $headers );
 
 
 
 
 
 
375
 
376
- return $data;
377
  }
378
 
379
 
@@ -393,7 +736,7 @@ class Caldera_Forms {
393
  "name" => __('Redirect', 'caldera-forms'),
394
  "description" => __("Redirects user to URL on successful submit", 'caldera-forms'),
395
  "template" => CFCORE_PATH . "processors/redirect/config.php",
396
- "single" => true
397
  )
398
  );
399
 
@@ -401,25 +744,199 @@ class Caldera_Forms {
401
 
402
  }
403
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  // get built in field types
405
- public function get_field_types($fields){
406
 
407
 
408
  $internal_fields = array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  'text' => array(
410
  "field" => "Single Line Text",
411
  "description" => __('Single Line Text', 'caldera-forms'),
412
  "file" => CFCORE_PATH . "fields/text/field.php",
413
  "category" => __("Text Fields,Basic", "cladera-forms"),
414
  "setup" => array(
 
415
  "preview" => CFCORE_PATH . "fields/text/preview.php"
 
 
 
 
416
  )
417
  ),
418
  'file' => array(
419
  "field" => "File",
420
  "description" => __('File Uploader', 'caldera-forms'),
421
  "file" => CFCORE_PATH . "fields/file/field.php",
422
- "handler" => array($this, 'handle_file_upload'),
423
  "viewer" => array($this, 'handle_file_view'),
424
  "category" => __("Basic,File", "cladera-forms"),
425
  "setup" => array(
@@ -473,6 +990,7 @@ class Caldera_Forms {
473
  "description" => __('Hidden', 'caldera-forms'),
474
  "file" => CFCORE_PATH . "fields/hidden/field.php",
475
  "category" => __("Text Fields,Basic", "cladera-forms"),
 
476
  "setup" => array(
477
  "preview" => CFCORE_PATH . "fields/hidden/preview.php",
478
  "template" => CFCORE_PATH . "fields/hidden/setup.php",
@@ -493,7 +1011,7 @@ class Caldera_Forms {
493
  "template" => CFCORE_PATH . "fields/button/config_template.html",
494
  "preview" => CFCORE_PATH . "fields/button/preview.php",
495
  "default" => array(
496
- 'class' => 'btn btn-primary',
497
  'type' => 'submit'
498
  ),
499
  "not_supported" => array(
@@ -510,7 +1028,8 @@ class Caldera_Forms {
510
  "file" => CFCORE_PATH . "fields/email/field.php",
511
  "category" => __("Text Fields,Basic", "cladera-forms"),
512
  "setup" => array(
513
- "preview" => CFCORE_PATH . "fields/email/preview.php"
 
514
  )
515
  ),
516
  'paragraph' => array(
@@ -532,6 +1051,7 @@ class Caldera_Forms {
532
  "category" => __("Select Options,Special", "cladera-forms"),
533
  "file" => CFCORE_PATH . "fields/toggle_switch/field.php",
534
  "options" => "single",
 
535
  "setup" => array(
536
  "template" => CFCORE_PATH . "fields/toggle_switch/config_template.html",
537
  "preview" => CFCORE_PATH . "fields/toggle_switch/preview.php",
@@ -558,6 +1078,7 @@ class Caldera_Forms {
558
  "file" => CFCORE_PATH . "fields/dropdown/field.php",
559
  "category" => __("Select Options,Basic", "cladera-forms"),
560
  "options" => "single",
 
561
  "setup" => array(
562
  "template" => CFCORE_PATH . "fields/dropdown/config_template.html",
563
  "preview" => CFCORE_PATH . "fields/dropdown/preview.php",
@@ -575,6 +1096,7 @@ class Caldera_Forms {
575
  "file" => CFCORE_PATH . "fields/checkbox/field.php",
576
  "category" => __("Select Options,Basic", "cladera-forms"),
577
  "options" => "multiple",
 
578
  "setup" => array(
579
  "preview" => CFCORE_PATH . "fields/checkbox/preview.php",
580
  "template" => CFCORE_PATH . "fields/checkbox/config_template.html",
@@ -592,6 +1114,7 @@ class Caldera_Forms {
592
  "file" => CFCORE_PATH . "fields/radio/field.php",
593
  "category" => __("Select Options,Basic", "cladera-forms"),
594
  "options" => true,
 
595
  "setup" => array(
596
  "preview" => CFCORE_PATH . "fields/radio/preview.php",
597
  "template" => CFCORE_PATH . "fields/radio/config_template.html",
@@ -663,75 +1186,123 @@ class Caldera_Forms {
663
 
664
  }
665
 
666
- static public function check_condition($conditions, $data, $form){
667
 
668
  $trues = array();
669
  if(empty($conditions['group'])){
670
  return true;
671
  }
 
 
672
  foreach($conditions['group'] as $groupid=>$lines){
673
  $truelines = array();
674
 
675
  foreach($lines as $lineid=>$line){
676
- $truelines[$lineid] = false;
677
 
678
- if(!empty($line['field']) && isset($form['fields'][$line['field']])){
679
-
680
- // if not sent - preset it to a null value.
681
- if(!isset($data[$form['fields'][$line['field']]['slug']])){
682
- $prevalue = '';
683
- }else{
684
- $prevalue = $data[$form['fields'][$line['field']]['slug']];
 
 
685
  }
 
 
686
 
687
- foreach( (array) $prevalue as $value){
688
-
689
- switch ($line['compare']) {
690
- case 'is':
691
- if($value == $line['value']){
692
- $truelines[$lineid] = true;
693
- }
694
- break;
695
- case 'isnot':
696
 
697
- if($value != $line['value']){
698
- $truelines[$lineid] = true;
699
- }
700
- break;
701
- case '>':
702
- if($value > $line['value']){
703
- $truelines[$lineid] = true;
704
- }
705
- break;
706
- case '<':
707
- if($value < $line['value']){
708
- $truelines[$lineid] = true;
709
- }
710
- break;
711
- case 'startswith':
712
- if( substr( $value, 0, strlen($line['value']) ) == $line['value']){
713
- $truelines[$lineid] = true;
714
- }
715
- break;
716
- case 'endswith':
717
- if( substr( $value, strlen($value)-strlen($line['value']) ) == $line['value']){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
718
  $truelines[$lineid] = true;
719
  }
720
- break;
721
- case 'contains':
722
- if( false !== strpos( $value, $line['value'] ) ){
 
 
 
 
 
 
 
 
723
  $truelines[$lineid] = true;
724
  }
725
- break;
 
 
 
 
726
  }
727
-
728
- }
 
 
 
 
 
 
 
 
 
 
729
  }
 
730
  }
731
 
732
  $trues[$groupid] = in_array(false, $truelines) ? false : true;
733
  }
734
-
735
  if($conditions['type'] == 'use' || $conditions['type'] == 'show'){
736
  if(in_array(true, $trues)){
737
  return true;
@@ -747,24 +1318,683 @@ class Caldera_Forms {
747
  }
748
 
749
  // FRONT END STUFFF
750
- static public function form_redirect($type, $url, $data, $form, $processid){
751
 
752
- do_action('caldera_forms_redirect', $type, $url, $data, $form, $processid);
753
- do_action('caldera_forms_redirect_' . $type, $url, $data, $form, $processid);
754
-
755
- $url = apply_filters('caldera_forms_redirect', $url, $data, $form, $processid);
756
- $url = apply_filters('caldera_forms_redirect' . $type, $url, $data, $form, $processid);
757
 
 
 
 
758
  if(!empty($url)){
759
  wp_redirect( $url );
760
  exit;
761
  }
762
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
763
 
764
  static public function process_submission(){
765
- global $post, $front_templates, $wp_query, $processID, $form;
 
 
 
 
 
 
 
 
766
 
767
- $referrer = parse_url( $_POST['_wp_http_referer'] );
 
 
 
 
 
 
768
  if(!empty($referrer['query'])){
769
  parse_str($referrer['query'], $referrer['query']);
770
  if(isset($referrer['query']['cf_er'])){
@@ -774,165 +2004,228 @@ class Caldera_Forms {
774
  unset($referrer['query']['cf_su']);
775
  }
776
  }
 
777
  $form = get_option( $_POST['_cf_frm_id'] );
778
  if(empty($form['ID']) || $form['ID'] != $_POST['_cf_frm_id']){
779
  return;
780
  }
 
 
781
 
782
- unset($_POST['_wp_http_referer']);
783
-
784
- // unset stuff
785
- unset($_POST['_cf_frm_id']);
786
- unset($_POST['_cf_verify']);
787
-
788
  $form_instance_number = 1;
789
  if(isset($_POST['_cf_frm_ct'])){
790
  $form_instance_number = $_POST['_cf_frm_ct'];
791
  }
792
 
 
 
793
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
794
  // SET process ID
795
- $processID = uniqid('_cf_process_');
 
 
796
 
797
- // get data ready
798
- $rawdata = stripslashes_deep( $_POST );
799
- $data = array();
800
- foreach($form['fields'] as $field_slug=>$field){
801
- if(isset($_POST[$field_slug])){
802
- $data[$field['slug']] = $_POST[$field_slug];
803
- }
804
- }
805
- $process_data = $data;
806
 
807
- // init filter
808
- $form = apply_filters('caldera_forms_submit_get_form', $form, $process_data, $referrer, $processID);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
809
 
810
- // get all fieldtype
811
- $field_types = apply_filters('caldera_forms_get_field_types', array() );
812
 
813
  // start action
814
- do_action('caldera_forms_submit_start', $data, $form, $referrer, $processID);
815
 
 
 
 
 
 
 
 
 
 
816
  // requireds
817
  // set transient for returns submittions
818
- $transdata = array(
819
- 'transient' => $processID,
820
- 'form_instance' => $form_instance_number,
821
- 'expire' => 120,
822
- 'data' => $data
823
- );
824
-
825
- $transdata = apply_filters('caldera_forms_submit_transient', $transdata, $process_data, $form, $referrer, $processID);
 
 
 
 
 
 
826
 
827
  // setup processor bound requieds
828
  if(!empty($form['processors'])){
829
  $bound_fields = array();
830
  foreach($form['processors'] as $processor_id=>$processor){
831
- if(!empty($processor['config'])){
 
832
  foreach($processor['config'] as $slug=>&$value){
833
- $bound_fields = array_merge($bound_fields, self::search_array_fields($value, array_keys( $form['fields'])) );
 
 
 
 
 
 
 
 
 
 
834
  }
835
  }
836
  }
837
- foreach($bound_fields as $bound){
838
- $form['fields'][$bound]['required'] = 1;
839
- }
840
  }
841
 
842
- // field handlers + required checks
843
- foreach($form['fields'] as $field){
844
-
845
- // setfield
846
- $field = apply_filters('caldera_forms_render_setup_field', $field, $form);
847
- if(empty($field)){
848
- continue;
849
- }
850
- // handler
851
- if(isset($field_types[$field['type']]['handler']) && isset($process_data[$field['slug']])){
852
-
853
- if(is_array($field_types[$field['type']]['handler'])){
854
- $process_data[$field['slug']] = call_user_func_array($field_types[$field['type']]['handler'],array($process_data[$field['slug']], $field, $data, $form));
 
855
  }else{
856
- if(function_exists($field_types[$field['type']]['handler'])){
857
- $func = $field_types[$field['type']]['handler'];
858
- $process_data[$field['slug']] = $func($process_data[$field['slug']], $field, $process_data, $form);
 
 
 
859
  }
860
  }
861
- if(is_array($process_data[$field['slug']]) && isset($process_data[$field['slug']]['_fail'])){
862
- $transdata['fields'][$field['slug']] = $process_data[$field['slug']]['_fail'];
863
- }
864
  }
865
 
866
- // required check
867
- $failed = false;
868
- if(!empty($field['required'])){
869
-
870
- // check if conditions match first.
871
- if(!empty($field['conditions']['type'])){
872
- if(!self::check_condition($field['conditions'], $process_data, $form)){
873
- continue;
874
- }
875
- }
876
 
877
 
878
- if(isset($process_data[$field['slug']])){
879
- if(is_array($process_data[$field['slug']])){
880
- if(count($process_data[$field['slug']]) <= 0){
881
- $failed = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
882
  }
883
- }else{
884
- if(strlen($process_data[$field['slug']]) < 1){
885
- $failed = true;
886
- }
887
  }
888
- }else{
889
- $failed = true;
890
- }
891
- if($failed === true){
892
- $transdata['fields'][$field['slug']] = $field['slug'] .' ' .__('is required', 'caldera-forms');
 
893
  }
894
  }
895
 
896
  }
897
 
898
  // check requireds
899
- if(!empty($transdata['fields'])){
900
  $transdata['type'] = 'error';
901
  // set error transient
902
- $transdata = apply_filters('caldera_forms_submit_error_transient', $transdata, $process_data, $form, $referrer, $processID);
903
- $transdata = apply_filters('caldera_forms_submit_error_transient_required', $transdata, $process_data, $form, $referrer, $processID);
904
-
905
- set_transient( $processID, $transdata, $transdata['expire']);
906
-
907
  // back to form
908
  $query_str = array(
909
- 'cf_er' => $processID
910
  );
911
  if(!empty($referrer['query'])){
912
  $query_str = array_merge($referrer['query'], $query_str);
913
  }
914
  $referrer = $referrer['path'] . '?' . http_build_query($query_str);
915
- $referrer = apply_filters('caldera_forms_submit_error_redirect', $referrer, $process_data, $form, $processID);
916
- $referrer = apply_filters('caldera_forms_submit_error_redirect_required', $referrer, $process_data, $form, $processID);
 
 
917
 
918
- return self::form_redirect('error', $referrer, $process_data, $form, $processID );
919
  }
920
 
921
 
922
  // has processors
923
- do_action('caldera_forms_submit_start_processors', $process_data, $form, $referrer, $processID);
924
  if(!empty($form['processors'])){
925
 
926
  // get all form processors
927
  $form_processors = apply_filters('caldera_forms_get_form_processors', array() );
928
- do_action('caldera_forms_submit_pre_process', $process_data, $form, $referrer, $processID);
 
 
929
  foreach($form['processors'] as $processor_id=>$processor){
930
 
931
  if(isset($form_processors[$processor['type']])){
932
 
933
  // Do Conditional
934
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
935
- if(!self::check_condition($processor['conditions'], $process_data, $form)){
936
  continue;
937
  }
938
  }
@@ -942,94 +2235,87 @@ class Caldera_Forms {
942
  if(!isset($process['pre_processor'])){
943
  continue;
944
  }
 
945
  // set default config
946
  $config = array();
 
 
947
  if(isset($process['default'])){
948
  $config = $process['default'];
949
  }
950
  if(!empty($processor['config'])){
951
 
952
- // reset bindings
953
- foreach($processor['config'] as $slug=>&$value){
954
- if(!is_array($value)){
955
- // reset binding
956
- if(isset($form['fields'][$value])){
957
- $value = $form['fields'][$value]['slug'];
958
- }
959
- }
960
- }
961
  $config = array_merge($config, $processor['config']);
962
  }
963
  if(is_array($process['pre_processor'])){
964
- $process_line_data = call_user_func_array($process['pre_processor'],array($process_data, $config, $data, $form));
965
  }else{
966
  if(function_exists($process['pre_processor'])){
967
  $func = $process['pre_processor'];
968
- $process_line_data = $func($process_data, $config, $data, $form);
969
  }
970
  }
971
- if(empty($process_line_data) || false === $process_line_data){
972
- // processor killed it- replace with original data.
973
- $process_line_data = $data;
974
- }elseif(!empty($process_line_data)){
975
- if(is_array($process_line_data) && isset($process_line_data['_fail'])){
976
  //type
977
- if(!empty($process_line_data['_fail']['type'])){
978
- $transdata['type'] = $process_line_data['_fail']['type'];
979
  // has note?
980
- if(!empty($process_line_data['_fail']['note'])){
981
- $transdata['note'] = $process_line_data['_fail']['note'];
982
  }
983
  }
984
 
985
  // fields involved?
986
- if(!empty($process_line_data['_fail']['fields'])){
987
- $transdata['fields'] = $process_line_data['_fail']['fields'];
988
  }
989
 
990
  // set error transient
991
- $transdata = apply_filters('caldera_forms_submit_error_transient', $transdata, $process_data, $form, $referrer, $processID);
992
- $transdata = apply_filters('caldera_forms_submit_error_transient_pre_process', $transdata, $process_data, $form, $referrer, $processID);
993
-
994
- set_transient( $processID, $transdata, $transdata['expire']);
995
 
996
  // back to form
997
  $query_str = array(
998
- 'cf_er' => $processID
999
  );
1000
  if(!empty($referrer['query'])){
1001
  $query_str = array_merge($referrer['query'], $query_str);
1002
  }
1003
  $referrer = $referrer['path'] . '?' . http_build_query($query_str);
1004
- $referrer = apply_filters('caldera_forms_submit_error_redirect', $referrer, $process_data, $form, $processID);
1005
- $referrer = apply_filters('caldera_forms_submit_error_redirect_pre_process', $referrer, $process_data, $form, $processID);
1006
- return self::form_redirect('fail', $referrer, $process_data, $form, $processID );
 
 
 
 
1007
  }
1008
- // processor returned data, use this instead
1009
- $process_data = $process_line_data;
1010
  }
1011
  }
1012
  }
1013
- $process_data = apply_filters('caldera_forms_submit_pre_process', $process_data, $form, $referrer, $processID);
1014
  /// AFTER PRE-PROCESS - check for errors etc to return else continue to process.
1015
 
1016
- do_action('caldera_forms_submit_process', $process_data, $form, $referrer, $processID);
1017
  /// PROCESS
1018
  foreach($form['processors'] as $processor_id=>$processor){
1019
  if(isset($form_processors[$processor['type']])){
1020
  // has processor
1021
  // Do Conditional
1022
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
1023
- if(!self::check_condition($processor['conditions'], $process_data, $form)){
1024
  continue;
1025
  }
1026
  }
1027
-
1028
  $process = $form_processors[$processor['type']];
1029
  if(!isset($process['processor'])){
1030
  continue;
1031
  }
1032
-
1033
  // set default config
1034
  $config = array();
1035
  if(isset($process['default'])){
@@ -1037,42 +2323,65 @@ class Caldera_Forms {
1037
  }
1038
  if(!empty($processor['config'])){
1039
 
1040
- // reset bindings
1041
- foreach($processor['config'] as $slug=>&$value){
1042
- if(!is_array($value)){
1043
- // reset binding
1044
- if(isset($form['fields'][$value])){
1045
- $value = $form['fields'][$value]['slug'];
1046
- }
1047
- }
1048
- }
1049
  $config = array_merge($config, $processor['config']);
1050
- }
1051
  if(is_array($process['processor'])){
1052
- $process_line_data = call_user_func_array($process['processor'],array($process_data, $config, $data, $form));
1053
  }else{
1054
- if(function_exists($process['processor'])){
1055
  $func = $process['processor'];
1056
- $process_line_data = $func($process_data, $config, $data, $form);
1057
  }
1058
  }
1059
- if(!empty($process_line_data)){
1060
- // processor returned data, use this instead
1061
- $process_data = $process_line_data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1062
  }
 
1063
  }
1064
  }
1065
- $process_data = apply_filters('caldera_forms_submit_process', $process_data, $form, $referrer, $processID);
1066
  // AFTER PROCESS - do post process for any additional stuff
 
1067
 
1068
- do_action('caldera_forms_submit_post_process', $process_data, $form, $referrer, $processID);
1069
  // POST PROCESS
1070
  foreach($form['processors'] as $processor_id=>$processor){
1071
  if(isset($form_processors[$processor['type']])){
1072
  // has processor
1073
  // Do Conditional
1074
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
1075
- if(!self::check_condition($processor['conditions'], $process_data, $form)){
1076
  continue;
1077
  }
1078
  }
@@ -1088,68 +2397,113 @@ class Caldera_Forms {
1088
  }
1089
  if(!empty($processor['config'])){
1090
 
1091
- // reset bindings
1092
- foreach($processor['config'] as $slug=>&$value){
1093
- if(!is_array($value)){
1094
- // reset binding
1095
- if(isset($form['fields'][$value])){
1096
- $value = $form['fields'][$value]['slug'];
1097
- }
1098
- }
1099
- }
1100
  $config = array_merge($config, $processor['config']);
1101
  }
1102
  if(is_array($process['post_processor'])){
1103
- $process_line_data = call_user_func_array($process['post_processor'],array($process_data, $config, $data, $form));
1104
  }else{
1105
  if(function_exists($process['post_processor'])){
1106
  $func = $process['post_processor'];
1107
- $process_line_data = $func($process_data, $config, $data, $form);
1108
  }
1109
  }
1110
- if(false === $process_line_data){
1111
- // return an error since a processor killed it!
1112
- return;
1113
- }elseif(!empty($process_line_data)){
1114
- // processor returned data, use this instead
1115
- $process_data = $process_line_data;
1116
  }
 
1117
  }
1118
  }
1119
- $process_data = apply_filters('caldera_forms_submit_post_process', $process_data, $form, $referrer, $processID);
1120
  }
1121
 
1122
  // done do action.
1123
- do_action('caldera_forms_submit_complete', $process_data, $form, $referrer, $processID);
1124
 
1125
  // redirect back or to result page
1126
  $referrer['query']['cf_su'] = $form_instance_number;
1127
  $referrer = $referrer['path'] . '?' . http_build_query($referrer['query']);
1128
 
1129
  // filter refer
1130
- $referrer = apply_filters('caldera_forms_submit_redirect', $referrer, $process_data, $form, $processID);
1131
- $referrer = apply_filters('caldera_forms_submit_redirect_complete', $referrer, $process_data, $form, $processID);
 
 
 
1132
 
1133
- return self::form_redirect('complete', $referrer, $process_data, $form, $processID );
1134
  }
1135
 
1136
  static public function check_forms_shortcode(){
1137
- global $post, $front_templates, $wp_query, $processID, $form;
1138
 
1139
- //HOOK IN post
1140
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1141
  if(isset($_POST['_cf_verify']) && isset( $_POST['_cf_frm_id'] )){
1142
  if(wp_verify_nonce( $_POST['_cf_verify'], 'caldera_forms_front' )){
1143
 
1144
  self::process_submission();
1145
  exit;
1146
 
1147
-
1148
  }
1149
-
1150
-
1151
  /// end form and redirect to submit page or result page.
1152
  }
 
 
1153
  if(empty($post)){
1154
  if(isset($wp_query->queried_object)){
1155
  $post = $wp_query->queried_object;
@@ -1162,7 +2516,7 @@ class Caldera_Forms {
1162
 
1163
  // get fields
1164
 
1165
- $field_types = apply_filters('caldera_forms_get_field_types', array() );
1166
 
1167
  foreach($field_types as $field_type){
1168
  //enqueue styles
@@ -1192,6 +2546,7 @@ class Caldera_Forms {
1192
  // if depts been set- scripts are used -
1193
  wp_enqueue_script( 'cf-frontend-script-init', CFCORE_URL . 'assets/js/frontend-script-init.js', array('jquery'), self::VERSION, true);
1194
  $style_includes = get_option( '_caldera_forms_styleincludes' );
 
1195
 
1196
  if(!empty($style_includes['grid'])){
1197
  wp_enqueue_style( 'cf-grid-styles', CFCORE_URL . 'assets/css/caldera-grid.css', array(), self::VERSION );
@@ -1226,7 +2581,7 @@ class Caldera_Forms {
1226
 
1227
  // has a form - get field type
1228
  if(!isset($field_types)){
1229
- $field_types = apply_filters('caldera_forms_get_field_types', array() );
1230
  }
1231
 
1232
  if(!empty($form['fields'])){
@@ -1287,7 +2642,6 @@ class Caldera_Forms {
1287
 
1288
  static function search_array_fields($needle, $haystack, $found = array()){
1289
 
1290
- //dump($haystack);
1291
  if(is_array($needle)){
1292
  foreach($needle as $pin){
1293
  $found = array_merge($found, self::search_array_fields($pin, $haystack));
@@ -1310,13 +2664,17 @@ class Caldera_Forms {
1310
  return;
1311
  }
1312
 
1313
- $field_types = apply_filters('caldera_forms_get_field_types', array() );
1314
 
1315
  $fields = array();
1316
  foreach ($form['fields'] as $field_id => $field) {
1317
  $fields[$field['slug']] = $field;
1318
  }
1319
  }
 
 
 
 
1320
  }
1321
 
1322
  global $wpdb;
@@ -1336,21 +2694,43 @@ class Caldera_Forms {
1336
  return array();
1337
  }
1338
  $data = array();
 
 
 
 
1339
  foreach($rawdata as $row){
 
 
 
 
 
 
1340
 
1341
  if(isset($fields[$row->slug])){
1342
  $field = $fields[$row->slug];
1343
 
1344
  if(isset($field_types[$field['type']]['viewer'])){
 
 
 
 
 
 
 
1345
 
 
 
 
1346
  if(is_array($field_types[$field['type']]['viewer'])){
1347
  $row->value = call_user_func_array($field_types[$field['type']]['viewer'],array($row->value, $field, $form));
1348
- }else{
1349
- if(function_exists($field_types[$field['type']]['viewer'])){
1350
- $func = $field_types[$field['type']]['viewer'];
1351
- $row->value = $func($row->value, $field, $form);
1352
- }
1353
- }
 
 
1354
  }
1355
 
1356
 
@@ -1390,8 +2770,7 @@ class Caldera_Forms {
1390
  $row->value = $line;
1391
  }
1392
 
1393
-
1394
- $data['date'] = $row->_date_submitted;
1395
  $data['user'] = $row->_user_id;
1396
 
1397
  $data['data'][$row->slug]['label'] = $field['label'];
@@ -1402,9 +2781,39 @@ class Caldera_Forms {
1402
  }
1403
 
1404
  }else{
 
1405
  $data[$row->slug] = $row->value;
1406
  }
1407
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1408
  if(!empty($_POST['form'])){
1409
  header('Content-Type: application/json');
1410
  echo json_encode( $data );
@@ -1422,28 +2831,54 @@ class Caldera_Forms {
1422
  }
1423
 
1424
 
1425
-
1426
  if(is_string($atts)){
 
 
 
 
 
 
 
 
 
1427
  $atts = array( 'id' => $atts);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1428
  }
1429
 
1430
- if(empty($atts['id'])){
1431
- return;
 
1432
  }
 
 
1433
 
1434
- $form = get_option( $atts['id'] );
1435
  if(empty($form)){
1436
  return;
1437
  }
1438
 
1439
- $form = apply_filters('caldera_forms_render_get_form', $form );
1440
-
1441
  if(empty($current_form_count)){
1442
  $current_form_count = 0;
1443
  }
1444
  $current_form_count += 1;
1445
 
1446
- $field_types = apply_filters('caldera_forms_get_field_types', array() );
1447
 
1448
  do_action('caldera_forms_render_start', $form);
1449
 
@@ -1474,7 +2909,20 @@ class Caldera_Forms {
1474
 
1475
  $grid = new Caldera_Form_Grid($grid_settings);
1476
 
1477
- $grid->setLayout($form['layout_grid']['structure']);
 
 
 
 
 
 
 
 
 
 
 
 
 
1478
 
1479
  // setup notcies
1480
  $notices = array();
@@ -1505,12 +2953,50 @@ class Caldera_Forms {
1505
 
1506
  $field_errors = array();
1507
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1508
  // check for prev post
1509
- $prev_data = false;
1510
 
1511
  // load requested data
1512
  if(!empty($entry_id)){
1513
- $prev_data = Caldera_Forms::get_entry($entry_id);
1514
  $prev_data = apply_filters('caldera_forms_render_get_entry', $prev_data, $form, $entry_id);
1515
  }
1516
 
@@ -1520,13 +3006,32 @@ class Caldera_Forms {
1520
  if(!empty($prev_post['transient'])){
1521
 
1522
  if($prev_post['transient'] === $_GET['cf_er']){
1523
- $prev_data = $prev_post['data'];
 
 
 
 
 
 
 
 
 
1524
  }
1525
  if(!empty($prev_post['type']) && !empty($prev_post['note'])){
1526
  $notices[$prev_post['type']]['note'] = $prev_post['note'];
1527
  }
 
 
 
1528
  if(!empty($prev_post['fields'])){
1529
- $field_errors = $prev_post['fields'];
 
 
 
 
 
 
 
1530
  }
1531
  }
1532
  // filter transient
@@ -1539,13 +3044,56 @@ class Caldera_Forms {
1539
  }
1540
  }
1541
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1542
  // setup processor bound requieds
1543
  if(!empty($form['processors'])){
1544
- $bound_fields = array();
1545
  foreach($form['processors'] as $processor_id=>$processor){
1546
- if(!empty($processor['config'])){
1547
  foreach($processor['config'] as $slug=>&$value){
1548
- $bound_fields = array_merge($bound_fields, self::search_array_fields($value, array_keys( $form['fields'])) );
 
 
 
 
 
1549
  }
1550
  }
1551
  }
@@ -1556,18 +3104,19 @@ class Caldera_Forms {
1556
 
1557
  $conditions_templates = array();
1558
  $conditions_configs = array();
 
1559
  if(!empty($form['layout_grid']['fields'])){
1560
 
1561
  foreach($form['layout_grid']['fields'] as $field_base_id=>$location){
1562
-
1563
  if(isset($form['fields'][$field_base_id])){
1564
-
1565
  $field = apply_filters('caldera_forms_render_setup_field', $form['fields'][$field_base_id], $form);
1566
 
1567
  if(empty($field) || !isset($field_types[$field['type']]['file']) || !file_exists($field_types[$field['type']]['file'])){
1568
  continue;
1569
  }
1570
-
1571
  $field_classes = array(
1572
  "control_wrapper" => "form-group",
1573
  "field_label" => "control-label",
@@ -1578,9 +3127,9 @@ class Caldera_Forms {
1578
  "field_error" => "has-error",
1579
  );
1580
 
1581
- $field_classes = apply_filters('caldera_forms_render_field_classes', $field_classes, $form);
1582
- $field_classes = apply_filters('caldera_forms_render_field_classes_type-' . $field['type'], $field_classes, $form);
1583
- $field_classes = apply_filters('caldera_forms_render_field_classes_slug-' . $field['slug'], $field_classes, $form);
1584
 
1585
  $field = apply_filters('caldera_forms_render_get_field', $field, $form);
1586
  $field = apply_filters('caldera_forms_render_get_field_type-' . $field['type'], $field, $form);
@@ -1610,7 +3159,8 @@ class Caldera_Forms {
1610
 
1611
  // value
1612
  if(isset($field['config']['default'])){
1613
- $field_structure['field_value'] = $field['config']['default'];
 
1614
  }
1615
 
1616
  // transient data
@@ -1639,8 +3189,13 @@ class Caldera_Forms {
1639
 
1640
  // conditional wrapper
1641
  if(!empty($field['conditions']['group']) && !empty($field['conditions']['type'])){
1642
- // wrap it up
1643
 
 
 
 
 
 
 
1644
  $conditions_templates[$field_base_id] = "<script type=\"text/html\" id=\"conditional-" . $field_base_id . "-tmpl\">\r\n" . $field_html . "</script>\r\n";
1645
  $conditions_configs[$field_base_id] = $field['conditions'];
1646
  if($field['conditions']['type'] == 'show'){
@@ -1659,10 +3214,11 @@ class Caldera_Forms {
1659
  //
1660
  $grid = apply_filters('caldera_forms_render_grid_structure', $grid, $form);
1661
 
1662
- $out = "<div class=\"caldera-grid\">\r\n";
1663
-
1664
  $notices = apply_filters('caldera_forms_render_notices', $notices, $form);
1665
 
 
1666
  if(!empty($notices)){
1667
  // do notices
1668
  foreach($notices as $note_type => $notice){
@@ -1672,11 +3228,14 @@ class Caldera_Forms {
1672
  }
1673
 
1674
  }
 
 
1675
 
1676
- if(empty($notices['success'])){
1677
 
1678
  $form_classes = array(
1679
- 'caldera_forms_form'
 
1680
  );
1681
 
1682
  $form_attributes = array(
@@ -1685,6 +3244,7 @@ class Caldera_Forms {
1685
  'role' => 'form'
1686
  );
1687
 
 
1688
  $form_classes = apply_filters('caldera_forms_render_form_classes', $form_classes, $form);
1689
  $form_attributes = apply_filters('caldera_forms_render_form_attributes', $form_attributes, $form);
1690
 
@@ -1694,27 +3254,91 @@ class Caldera_Forms {
1694
  }
1695
 
1696
  // render only non success
1697
- $out .= "<form class=\"" . implode(' ', $form_classes) . "\" " . implode(" ", $attributes) . ">\r\n";
1698
  $out .= wp_nonce_field( "caldera_forms_front", "_cf_verify", true, false);
1699
  $out .= "<input type=\"hidden\" name=\"_cf_frm_id\" value=\"" . $atts['id'] . "\">\r\n";
1700
  $out .= "<input type=\"hidden\" name=\"_cf_frm_ct\" value=\"" . $current_form_count . "\">\r\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1701
  $out .= $grid->renderLayout();
1702
- $out .= "</form>\r\n";
1703
  }
1704
 
1705
  $out .= "</div>\r\n";
1706
 
1707
  // output javascript conditions.
1708
  if(!empty($conditions_configs) && !empty($conditions_templates)){
1709
- echo "<script>\r\n";
1710
- echo "var caldera_conditionals = " . json_encode($conditions_configs) . ";\r\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1711
  echo "</script>\r\n";
1712
  echo implode("\r\n", $conditions_templates);
1713
 
1714
  // enqueue conditionls app.
1715
  wp_enqueue_script( 'cf-frontend-conditionals', CFCORE_URL . 'assets/js/conditionals.js', array('jquery'), self::VERSION, true);
1716
  }
1717
-
1718
  do_action('caldera_forms_render_end', $form);
1719
 
1720
  return apply_filters('caldera_forms_render_form', $out, $form);
44
 
45
 
46
  // add element & fields filters
47
+ add_filter('caldera_forms_get_field_types', array( $this, 'get_internal_field_types'));
48
  add_filter('caldera_forms_get_form_processors', array( $this, 'get_form_processors'));
49
  add_filter('caldera_forms_submit_redirect_complete', array( $this, 'do_redirect'),10, 4);
50
+ add_action('caldera_forms_edit_end', array($this, 'calculations_templates') );
51
+
52
+ // magic tags
53
+ //add_filter('caldera_forms_render_magic_tag', array( $this, 'do_magic_tags'));
54
  // mailser
55
+ add_filter('caldera_forms_get_magic_tags', array( $this, 'set_magic_tags'),1);
56
  add_filter('caldera_forms_mailer', array( $this, 'mail_attachment_check'),10, 3);
57
 
58
  // action
59
+ add_action('caldera_forms_submit_complete', array( $this, 'save_final_form'),50);
 
60
 
61
  add_action("wp_ajax_get_entry", array( $this, 'get_entry') );
62
  // find if profile is loaded
65
  // render shortcode
66
  add_shortcode( 'caldera_form', array( $this, 'render_form') );
67
 
68
+ // check update version
69
+ $version = get_option('_calderaforms_lastupdate');
70
+ if(empty($version) || version_compare($version, CFCORE_VER) < 0){
71
+ self::activate_caldera_forms();
72
+ update_option('_calderaforms_lastupdate',CFCORE_VER);
73
+ wp_redirect( $_SERVER['REQUEST_URI'] );
74
+ exit;
75
+ }
76
+
77
  }
78
 
79
 
89
  load_textdomain( $domain, trailingslashit( WP_LANG_DIR ) . $domain . '/' . $domain . '-' . $locale . '.mo' );
90
  load_plugin_textdomain( $domain, FALSE, basename( dirname( __FILE__ ) ) . '/languages' );
91
  }
 
92
 
93
+ /// activator
94
+ public static function activate_caldera_forms(){
95
+ global $wpdb;
96
+
97
+ $tables = $wpdb->get_results("SHOW TABLES", ARRAY_A);
98
+ foreach($tables as $table){
99
+ $alltables[] = implode($table);
100
+ }
101
+
102
+ // meta table
103
+ if(!in_array($wpdb->prefix.'cf_form_entry_meta', $alltables)){
104
+ // create meta tables
105
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
106
+
107
+ $meta_table = "CREATE TABLE `" . $wpdb->prefix . "cf_form_entry_meta` (
108
+ `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
109
+ `entry_id` bigint(20) unsigned NOT NULL DEFAULT '0',
110
+ `process_id` varchar(255) DEFAULT NULL,
111
+ `meta_key` varchar(255) DEFAULT NULL,
112
+ `meta_value` longtext,
113
+ PRIMARY KEY (`meta_id`),
114
+ KEY `meta_key` (`meta_key`),
115
+ KEY `entry_id` (`entry_id`)
116
+ ) DEFAULT CHARSET=utf8;";
117
+
118
+ dbDelta( $meta_table );
119
 
120
+ }
121
 
122
+ if(!in_array($wpdb->prefix.'cf_form_entries', $alltables)){
123
+ // create tables
124
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
125
+
126
+ $entry_table = "CREATE TABLE `" . $wpdb->prefix . "cf_form_entries` (
127
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
128
+ `form_id` varchar(18) NOT NULL DEFAULT '',
129
+ `user_id` int(11) NOT NULL,
130
+ `datestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
131
+ `status` varchar(20) NOT NULL DEFAULT 'active',
132
+ PRIMARY KEY (`id`),
133
+ KEY `form_id` (`form_id`),
134
+ KEY `user_id` (`user_id`),
135
+ KEY `date_time` (`datestamp`),
136
+ KEY `status` (`status`)
137
+ ) DEFAULT CHARSET=utf8;";
138
+
139
+
140
+ dbDelta( $entry_table );
141
+
142
+ $values_table = "CREATE TABLE `" . $wpdb->prefix . "cf_form_entry_values` (
143
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
144
+ `entry_id` int(11) NOT NULL,
145
+ `field_id` varchar(20) NOT NULL,
146
+ `slug` varchar(255) NOT NULL DEFAULT '',
147
+ `value` longtext NOT NULL,
148
+ PRIMARY KEY (`id`),
149
+ KEY `form_id` (`entry_id`),
150
+ KEY `field_id` (`field_id`),
151
+ KEY `slug` (`slug`)
152
+ ) DEFAULT CHARSET=utf8;";
153
+
154
+ dbDelta( $values_table );
155
+
156
+ }else{
157
+ // check for field_id from 1.0.4
158
+ $columns = $wpdb->get_results("SHOW COLUMNS FROM `" . $wpdb->prefix . "cf_form_entry_values`", ARRAY_A);
159
+ $fields = array();
160
+ foreach($columns as $column){
161
+ $fields[] = $column['Field'];
162
+ }
163
+ if(!in_array('field_id', $fields)){
164
+ $wpdb->query( "ALTER TABLE `" . $wpdb->prefix . "cf_form_entry_values` ADD `field_id` varchar(20) NOT NULL AFTER `entry_id`;" );
165
+ $wpdb->query( "CREATE INDEX `field_id` ON `" . $wpdb->prefix . "cf_form_entry_values` (`field_id`); ");
166
+ // update all entries
167
+ $forms = $wpdb->get_results("SELECT `id`,`form_id` FROM `" . $wpdb->prefix . "cf_form_entries`", ARRAY_A);
168
+ $known = array();
169
+ if( !empty($forms)){
170
+ foreach($forms as $form){
171
+ if(!isset($known[$form['form_id']])){
172
+ $config = get_option($form['form_id']);
173
+ if(empty($config)){
174
+ continue;
175
+ }
176
+ $known[$form['form_id']] = $config;
177
+ }else{
178
+ $config = $known[$form['form_id']];
179
+ }
180
+
181
+ foreach($config['fields'] as $field_id=>$field){
182
+ $wpdb->update($wpdb->prefix . "cf_form_entry_values", array('field_id'=>$field_id), array('entry_id' => $form['id'], 'slug' => $field['slug']));
183
+ }
184
 
 
 
 
 
 
 
 
 
 
185
  }
186
  }
 
187
  }
188
+ // add status
189
+ $columns = $wpdb->get_results("SHOW COLUMNS FROM `" . $wpdb->prefix . "cf_form_entries`", ARRAY_A);
190
+ $fields = array();
191
+ if(!in_array('status', $fields)){
192
+ $wpdb->query( "ALTER TABLE `" . $wpdb->prefix . "cf_form_entries` ADD `status` varchar(20) NOT NULL DEFAULT 'active' AFTER `datestamp`;" );
193
+ $wpdb->query( "CREATE INDEX `status` ON `" . $wpdb->prefix . "cf_form_entries` (`status`); ");
194
+ }
195
+
196
+ }
197
 
198
+ }
199
 
 
200
 
201
+ public static function star_rating_viewer($value, $field, $form){
202
+
203
+ $out = "<div style=\"color: " . $field['config']['color'] . "; font-size: 10px;\" >";
204
+ if(!empty($field['config']['number'])){
205
+ for( $i = 1; $i <= $field['config']['number']; $i++){
206
+ $star = 'star-off-png';
207
+ if( $i<= $value){
208
+ $star = 'star-on-png';
209
+ }
210
+ $out .= '<span data-alt="'.$i.'" class="'.$star.'" title="'.$i.'" style="margin-right: -2px;"></span> ';
211
  }
212
  }
213
+ $out .= '</div>';
 
214
 
215
+ return $out;
216
+ }
217
 
218
  public static function handle_file_view($value, $field, $form){
219
 
224
  public static function mail_attachment_check($mail, $data, $form){
225
 
226
  // check for
227
+ foreach($form['fields'] as $field_id=>$field){
228
  if($field['type'] == 'file' && isset($field['config']['attach'])){
229
 
 
230
  $dir = wp_upload_dir();
231
+ $file = str_replace($dir['baseurl'], $dir['basedir'], self::get_field_data($field_id, $form));
232
  if(file_exists($file)){
233
  $mail['attachments'][] = $file;
234
  }
239
  }
240
 
241
 
242
+ public static function captcha_check($value, $field, $form){
243
+
244
+ if(empty($_POST['recaptcha_response_field'])){
245
  return array('_fail' => __("The reCAPTCHA field is required.", 'caldera-forms'));
246
  }
247
  include_once CFCORE_PATH . 'fields/recaptcha/recaptchalib.php';
248
 
249
+ $resp = recaptcha_check_answer($field['config']['private_key'], $_SERVER["REMOTE_ADDR"], $_POST['recaptcha_challenge_field'], $_POST['recaptcha_response_field']);
250
 
251
  if (!$resp->is_valid) {
252
  return array('_fail' => __("The reCAPTCHA wasn't entered correctly.", 'caldera-forms'));
254
  return true;
255
  }
256
 
257
+ public static function update_field_data($field, $entry_id, $form){
258
+ global $wpdb, $form;
259
 
260
+ $data = self::get_field_data($field['ID'], $form);
261
 
262
+ if(empty($data)){
263
+ return;
264
+ }
265
 
266
+ if( has_filter( 'caldera_forms_save_field' ) ){
267
+ $data = apply_filters( 'caldera_forms_update_field', $data, $field, $form );
268
+ }
269
+
270
+ if( has_filter( 'caldera_forms_save_field_' . $field['type'] ) ){
271
+ $data = apply_filters( 'caldera_forms_update_field_' . $field['type'], $data, $field, $form );
272
+ }
273
+
274
+ $wpdb->update($wpdb->prefix . 'cf_form_entry_values', array('value' => $data), array('entry_id' => $entry_id, 'field_id' => $field['ID']));
275
 
276
+ }
277
+
278
+
279
+ public static function save_field_data($field, $entry_id, $form){
280
+ global $wpdb, $form;
281
+
282
+ $data = self::get_field_data($field['ID'], $form);
283
+ if(empty($data)){
284
+ return;
285
+ }
286
+
287
+ foreach((array) $data as $key=>$entry){
288
+
289
+ if( has_filter( 'caldera_forms_save_field' ) ){
290
+ $entry = apply_filters( 'caldera_forms_save_field', $entry, $field );
291
+ }
292
+
293
+ if( has_filter( 'caldera_forms_save_field_' . $field['type'] ) ){
294
+ $entry = apply_filters( 'caldera_forms_save_field_' . $field['type'], $entry, $field );
295
+ }
296
+
297
+ $field_item = array(
298
+ 'entry_id' => $entry_id,
299
+ 'field_id' => $field['ID'],
300
+ 'slug' => $field['slug'],
301
+ 'value' => $entry
302
  );
303
+ // named key kets .key to slug
304
+ if(!is_int($key)){
305
+ // Keyed
306
+ $keyed = true;
307
+ $field_item['slug'] .= '.'.$key;
308
+ }
309
+ // Save
310
+ $wpdb->insert($wpdb->prefix . 'cf_form_entry_values', $field_item);
311
+ }
312
+
313
+ if(!empty($keyed)){
314
 
315
+ if( has_filter( 'caldera_forms_save_field_combined' . $field['type'] ) ){
316
+ $data = apply_filters( 'caldera_forms_save_field_combined' . $field['type'], $entry, $field );
317
+ }
318
+
319
+ $field_item = array(
320
+ 'entry_id' => $entry_id,
321
+ 'field_id' => $field['ID'],
322
+ 'slug' => $field['slug'],
323
+ 'value' => json_encode( $data )
324
+ );
325
+ $wpdb->insert($wpdb->prefix . 'cf_form_entry_values', $field_item);
326
+ }
327
+
328
+ }
329
+
330
+ public static function save_final_form($form){
331
+ global $wpdb, $processed_meta;
332
+
333
+ // check submit type (new or update)
334
+ if(isset($_POST['_cf_frm_edt'])){
335
+ // is edit
336
+ //check user can edit this item.
337
+ $user_id = get_current_user_id();
338
+ if(!empty($user_id)){
339
+ $details = self::get_entry_detail($_POST['_cf_frm_edt'], $form);
340
+ if(!empty($details)){
341
+ // check user can edit
342
+ if( current_user_can( 'edit_posts' ) || $details['user_id'] === $user_id ){
343
+ $entryid = $_POST['_cf_frm_edt'];
344
  }else{
345
+ return new WP_Error( 'error', __( "Permission denied.", "caldera-forms" ) );
 
 
 
 
 
 
346
  }
347
+ }
348
+
349
+ }
350
+
351
+ }
352
+
353
+ if(!empty($form['db_support'])){
354
+ // new entry or update
355
+ if(empty($entryid)){
356
+ $new_entry = array(
357
+ 'form_id' => $form['ID'],
358
+ 'user_id' => 0,
359
+ 'datestamp' => date_i18n( 'Y-m-d H:i:s', time(), 0)
360
+ );
361
+ // if user logged in
362
+ if(is_user_logged_in()){
363
+ $new_entry['user_id'] = get_current_user_id();
364
  }else{
365
+ if(isset($data['_user_id'])){
366
+ $new_entry['user_id'] = $data['_user_id'];
367
+ }
368
+ }
369
+
370
+ $wpdb->insert($wpdb->prefix . 'cf_form_entries', $new_entry);
371
+ $entryid = $wpdb->insert_id;
372
+
373
+ foreach($form['fields'] as $field_id=>$field){
374
+ // add new and update
375
+ self::save_field_data($field, $entryid, $form);
376
+
377
  }
378
+
379
+ // save form meta if any
380
+ if(isset($processed_meta[$form['ID']])){
381
+ foreach($processed_meta[$form['ID']] as $process_id=>$meta_data){
382
+
383
+ foreach($meta_data as $meta_key=>$meta_value){
384
+
385
+ if(count($meta_value) > 1){
386
+ $meta_value = json_encode($meta_value);
387
+ }else{
388
+ $meta_value = $meta_value[0];
389
+ if(is_array($meta_value) || is_object($meta_value)){
390
+ $meta_value = json_encode($meta_value);
391
+ }
392
+ }
393
+
394
+ $meta_entry = array(
395
+ 'entry_id' => $entryid,
396
+ 'process_id' => $process_id,
397
+ 'meta_key' => $meta_key,
398
+ 'meta_value' => $meta_value
399
+ );
400
+
401
+ $wpdb->insert($wpdb->prefix . 'cf_form_entry_meta', $meta_entry);
402
+
403
+ }
404
+
405
+ }
406
+ }
407
+
408
+ }else{
409
+
410
+ // do update
411
+ foreach($form['fields'] as $field_id=>$field){
412
+ // add new and update
413
+ self::update_field_data($field, $entryid, $form);
414
+
415
+ }
416
+ if(isset($processed_meta[$form['ID']])){
417
+ foreach($processed_meta[$form['ID']] as $process_id=>$meta_data){
418
+
419
+ foreach($meta_data as $meta_key=>$meta_value){
420
+
421
+ if(count($meta_value) > 1){
422
+ $meta_value = json_encode($meta_value);
423
+ }else{
424
+ $meta_value = $meta_value[0];
425
+ }
426
+
427
+ $meta_entry = array(
428
+ 'entry_id' => $entryid,
429
+ 'process_id' => $process_id,
430
+ 'meta_key' => $meta_key,
431
+ 'meta_value' => $meta_value
432
+ );
433
+ $wpdb->insert($wpdb->prefix . 'cf_form_entry_meta', $meta_entry);
434
+
435
+ }
436
+
437
+ }
438
+ }
439
+ // return
440
+ return;
441
  }
442
 
443
  }
450
  $sendername = __('Caldera Forms Notification', 'caldera-forms');
451
  if(!empty($form['mailer']['sender_name'])){
452
  $sendername = $form['mailer']['sender_name'];
453
+ if( false !== strpos($sendername, '%')){
454
+ $isname = self::get_slug_data( trim($sendername, '%'), $form);
455
+ if(!empty( $isname )){
456
+ $sendername = $isname;
457
+ }
458
+ }
459
  }
460
  if(empty($form['mailer']['sender_email'])){
461
  $sendermail = get_option( 'admin_email' );
462
  }else{
463
  $sendermail = $form['mailer']['sender_email'];
464
+ if( false !== strpos($sendermail, '%')){
465
+ $ismail = self::get_slug_data( trim($sendermail, '%'), $form);
466
+ if(is_email( $ismail )){
467
+ $sendermail = $ismail;
468
+ }
469
+ }
470
+ }
471
+ // use summary
472
+ if(empty($form['mailer']['email_message'])){
473
+ $form['mailer']['email_message'] = "{summary}";
474
  }
475
 
476
  $mail = array(
477
  'recipients' => array(),
478
+ 'subject' => self::do_magic_tags($form['mailer']['email_subject']),
479
  'message' => $form['mailer']['email_message']."\r\n",
480
  'headers' => array(
481
+ self::do_magic_tags( 'From: ' . $sendername . ' <' . $sendermail . '>' )
482
  ),
483
  'attachments' => array()
484
  );
485
 
486
+ // Filter Mailer first as not to have user input be filtered
487
+ $mail['message'] = self::do_magic_tags($mail['message']);
488
+
489
  if($form['mailer']['email_type'] == 'html'){
490
  $mail['headers'][] = "Content-type: text/html";
491
+ $mail['message'] = nl2br($mail['message']);
492
  }
493
 
494
+ // get tags
495
+ preg_match_all("/%(.+?)%/", $mail['message'], $hastags);
496
+ if(!empty($hastags[1])){
497
+ foreach($hastags[1] as $tag_key=>$tag){
498
+ $tagval = self::get_slug_data($tag, $form);
499
+ if(is_array($tagval)){
500
+ $tagval = implode(', ', $tagval);
501
+ }
502
+ $mail['message'] = str_replace($hastags[0][$tag_key], $tagval, $mail['message']);
503
+ }
504
+ }
505
+
506
+ //$mail['message']
507
+
508
+ // ifs
509
+ preg_match_all("/\[if (.+?)?\](?:(.+?)?\[\/if\])?/", $mail['message'], $hasifs);
510
+ if(!empty($hasifs[1])){
511
+ // process ifs
512
+ foreach($hasifs[0] as $if_key=>$if_tag){
513
+
514
+ $content = explode('[else]', $hasifs[2][$if_key]);
515
+ if(empty($content[1])){
516
+ $content[1] = '';
517
+ }
518
+ $vars = shortcode_parse_atts( $hasifs[1][$if_key]);
519
+ foreach($vars as $varkey=>$varval){
520
+ if(is_string($varkey)){
521
+ $var = self::get_slug_data($varkey, $form);
522
+ if( in_array($varval, (array) $var) ){
523
+ // yes show code
524
+ $mail['message'] = str_replace( $hasifs[0][$if_key], $content[0], $mail['message']);
525
+ }else{
526
+ // nope- no code
527
+ $mail['message'] = str_replace( $hasifs[0][$if_key], $content[1], $mail['message']);
528
+ }
529
+ }else{
530
+ $var = self::get_slug_data($varval, $form);
531
+ if(!empty($var)){
532
+ // show code
533
+ $mail['message'] = str_replace( $hasifs[0][$if_key], $content[0], $mail['message']);
534
+ }else{
535
+ // no code
536
+ $mail['message'] = str_replace( $hasifs[0][$if_key], $content[1], $mail['message']);
537
+ }
538
+ }
539
+ }
540
+ }
541
+
542
+ }
543
+
544
+
545
  if(!empty($form['mailer']['recipients'])){
546
  $mail['recipients'] = explode(',', $form['mailer']['recipients']);
547
  }else{
548
  $mail['recipients'][] = get_option( 'admin_email' );
549
  }
550
 
551
+ $data = self::get_submission_data($form);
552
+
553
  $submission = array();
554
+ foreach ($data as $field_id=>$row) {
555
+ if($row === null || !isset($form['fields'][$field_id]) ){
556
+ continue;
557
+ }
558
+
559
+ $key = $form['fields'][$field_id]['slug'];
560
+
561
  if(is_array($row)){
562
  $keys = array_keys($row);
563
  if(is_int($keys[0])){
564
  $row = implode(', ', $row);
565
  }else{
566
  $tmp = array();
567
+ foreach($row as $linekey=>$item){
568
  if(is_array($item)){
569
  $item = '( ' . implode(', ', $item).' )';
570
  }
571
+ $tmp[] = $linekey.': '.$item;
572
  }
573
  $row = implode(', ', $tmp);
574
  }
576
  $mail['message'] = str_replace('%'.$key.'%', $row, $mail['message']);
577
  $mail['subject'] = str_replace('%'.$key.'%', $row, $mail['subject']);
578
 
579
+ $submission[] = $row;
580
+ $labels[] = $form['fields'][$field_id]['label'];
581
  }
582
+
583
  // CSV
584
  if(!empty($form['mailer']['csv_data'])){
585
  ob_start();
586
  $df = fopen("php://output", 'w');
587
+ fputcsv($df, $labels);
588
  fputcsv($df, $submission);
589
  fclose($df);
590
  $csv = ob_get_clean();
592
  $mail['attachments'][] = $csvfile['file'];
593
  }
594
 
 
 
595
  if(empty($mail)){
596
  return;
597
  }
598
+
599
+ $mail = apply_filters( 'caldera_forms_mailer', $mail, $data, $form);
600
+
601
+ /*// recipients
602
  foreach($mail['recipients'] as &$recipient){
603
  // trim spaces
604
  $recipient = trim($recipient);
605
  }
606
  $recipients = implode(',', $mail['recipients']);
607
+ */
608
  $headers = implode("\r\n", $mail['headers']);
609
 
610
  do_action( 'caldera_forms_do_mailer', $mail, $data, $form);
611
  if(!empty($mail)){
612
+
613
+ if(wp_mail( (array) $mail['recipients'], $mail['subject'], $mail['message'], $headers, $mail['attachments'] )){
614
  // kill attachment.
615
  if(!empty($csvfile['file'])){
616
  if(file_exists($csvfile['file'])){
646
 
647
 
648
 
649
+ public static function do_redirect($referrer, $form, $processid){
650
  if(isset($form['processors'])){
651
  foreach($form['processors'] as $processor){
652
  if($processor['type'] == 'form_redirect'){
653
 
654
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
655
+ if(!self::check_condition($processor['conditions'], $form)){
656
  continue;
657
  }
658
  }
666
  return $referrer;
667
  }
668
 
669
+ public static function send_auto_response($config, $form){
670
+ global $form;
671
+
672
+ // remove required bounds.
673
+ unset($config['_required_bounds']);
674
 
675
  $message = $config['message'];
676
+ foreach($config as $tag=>&$value){
677
+ if($tag !== 'message'){
678
+ $message = str_replace('%'.$tag.'%', $value, $message);
679
+ $value = self::do_magic_tags( $value );
 
 
 
 
680
  }
 
681
  }
682
+ // set header
683
+ $headers = 'From: ' . $config['sender_name'] . ' <' . $config['sender_email'] . '>' . "\r\n";
684
+
685
+ $regex = "/%(.*?)%/";
686
+ preg_match_all($regex, $message, $matches);
687
+ if(!empty($matches[1])){
688
+ foreach($matches[1] as $key=>$tag){
689
+ $entry = self::get_slug_data($tag, $form);
690
+ if(!empty($entry)){
691
+ if(is_array($entry)){
692
+ if(count($entry) === 1){
693
+ $entry = array_shift($entry);
694
+ }elseif(count($entry) === 2){
695
+ $entry = implode(' & ', $entry);
696
+ }elseif(count($entry) > 2){
697
+ $last = array_pop($entry);
698
+ $entry = implode(', ', $entry).' & '.$last;
699
+ }else{
700
+ continue;
701
+ }
702
+ }
703
+ }else{
704
+ $entry = '';
705
+ }
706
 
707
+ $message = str_replace($matches[0][$key], $entry, $message);
 
 
 
 
 
708
  }
 
709
  }
710
+ $message = self::do_magic_tags( $message );
711
 
712
+ // setup mailer
713
+ $recipient_name = self::get_field_data($config['recipient_name'], $form);
714
+ $recipient_email = self::get_field_data($config['recipient_email'], $form);
715
+ $subject = $config['subject'];
716
+ do_action( 'caldera_forms_do_autoresponse', $config, $form);
717
+
718
+ wp_mail($recipient_name.' <'.$recipient_email.'>', $subject, $message, $headers );
719
 
 
720
  }
721
 
722
 
736
  "name" => __('Redirect', 'caldera-forms'),
737
  "description" => __("Redirects user to URL on successful submit", 'caldera-forms'),
738
  "template" => CFCORE_PATH . "processors/redirect/config.php",
739
+ "single" => false
740
  )
741
  );
742
 
744
 
745
  }
746
 
747
+ static public function run_calculation($value, $field, $form){
748
+
749
+ $formula = $field['config']['formular'];
750
+
751
+ // get manual
752
+ if(!empty($field['config']['manual'])){
753
+ $formula = $field['config']['manual_formula'];
754
+ preg_match_all("/%(.+?)%/", $formula, $hastags);
755
+ if(!empty($hastags[1])){
756
+ $binds = array();
757
+
758
+ foreach($hastags[1] as $tag_key=>$tag){
759
+
760
+ foreach($form['fields'] as $key_id=>$fcfg){
761
+ if($fcfg['slug'] === $tag){
762
+ $binds[] = '#'.$key_id;
763
+ $bindfields[] = '"'.$key_id.'"';
764
+ $formula = str_replace($hastags[0][$tag_key], $key_id, $formula);
765
+ }
766
+ }
767
+ }
768
+ }
769
+
770
+ }
771
+ if( empty($formula)){
772
+ return 0;
773
+ }
774
+
775
+ foreach($form['fields'] as $fid=>$cfg){
776
+ if(false !== strpos($formula, $fid)){
777
+ $entry_value = self::get_field_data($fid, $form);
778
+
779
+ if(is_array($entry_value)){
780
+ $number = floatval( array_sum( $entry_value ) );
781
+ }else{
782
+ $number = floatval( $entry_value );
783
+ }
784
+
785
+ $formula = str_replace($fid, $number, $formula);
786
+ }
787
+ }
788
+
789
+ $total = create_function(null, 'return '.$formula.';');
790
+ if(isset($field['config']['fixed'])){
791
+ return money_format('%i', $total() );
792
+ }
793
+ return $total();
794
+ }
795
+
796
+ static public function calculations_templates(){
797
+ include CFCORE_PATH . "fields/calculation/line-templates.php";
798
+ }
799
+
800
  // get built in field types
801
+ public function get_internal_field_types($fields){
802
 
803
 
804
  $internal_fields = array(
805
+ 'calculation' => array(
806
+ "field" => __("Calculation", "cladera-forms"),
807
+ "file" => CFCORE_PATH . "fields/calculation/field.php",
808
+ "handler" => array($this, "run_calculation"),
809
+ "category" => __("Special,Math", "cladera-forms"),
810
+ "description" => __('Calculate values', "cladera-forms"),
811
+ "setup" => array(
812
+ "template" => CFCORE_PATH . "fields/calculation/config.php",
813
+ "preview" => CFCORE_PATH . "fields/calculation/preview.php",
814
+ "default" => array(
815
+ 'element' => 'h3',
816
+ 'classes' => 'total-line',
817
+ 'before' => __('Total', 'caldera-forms').':',
818
+ 'after' => ''
819
+ ),
820
+ "styles" => array(
821
+ CFCORE_URL . "fields/calculation/style.css",
822
+ )
823
+ ),
824
+ "scripts" => array(
825
+ 'jquery'
826
+ )
827
+ ),
828
+ 'range_slider' => array(
829
+ "field" => __("Range Slider", 'caldera-forms'),
830
+ "file" => CFCORE_PATH . "fields/range_slider/field.php",
831
+ "category" => __("Special", "cladera-forms"),
832
+ "description" => __('Range Slider input field','caldera-forms'),
833
+ "setup" => array(
834
+ "template" => CFCORE_PATH . "fields/range_slider/config.php",
835
+ "preview" => CFCORE_PATH . "fields/range_slider/preview.php",
836
+ "default" => array(
837
+ 'default' => 1,
838
+ 'step' => 1,
839
+ 'min' => 0,
840
+ 'max' => 100,
841
+ 'showval' => 1,
842
+ 'suffix' => '',
843
+ 'prefix' => '',
844
+ 'color' => '#00ff00',
845
+ 'handle' => '#ffffff',
846
+ 'handleborder' => '#cccccc',
847
+ 'trackcolor' => '#e6e6e6'
848
+ ),
849
+ "scripts" => array(
850
+ 'jquery',
851
+ CFCORE_URL . "fields/range_slider/rangeslider.js",
852
+ ),
853
+ "styles" => array(
854
+ CFCORE_URL . "fields/range_slider/rangeslider.css",
855
+ )
856
+ ),
857
+ "scripts" => array(
858
+ 'jquery',
859
+ CFCORE_URL . "fields/range_slider/rangeslider.js",
860
+ ),
861
+ "styles" => array(
862
+ CFCORE_URL . "fields/range_slider/rangeslider.css",
863
+ )
864
+ ),
865
+ 'star_rating' => array(
866
+ "field" => __("Star Rating", 'caldera-forms'),
867
+ "file" => CFCORE_PATH . "fields/star-rate/field.php",
868
+ "category" => __("Feedback,Special", "cladera-forms"),
869
+ "description" => __('Star rating input for feedback','caldera-forms'),
870
+ "viewer" => array($this, 'star_rating_viewer'),
871
+ "setup" => array(
872
+ "template" => CFCORE_PATH . "fields/star-rate/config.php",
873
+ "preview" => CFCORE_PATH . "fields/star-rate/preview.php",
874
+ "default" => array(
875
+ 'number' => 5,
876
+ 'space' => 3,
877
+ 'size' => 13,
878
+ 'color' => '#FFAA00',
879
+ 'track_color'=> '#AFAFAF',
880
+ 'type'=> 'star',
881
+ ),
882
+ "scripts" => array(
883
+ 'jquery',
884
+ CFCORE_URL . "fields/star-rate/jquery.raty.js",
885
+ ),
886
+ "styles" => array(
887
+ //CFCORE_URL . "fields/star-rate/jquery.raty.css",
888
+ CFCORE_URL . "fields/star-rate/cf-raty.css",
889
+ )
890
+ ),
891
+ "scripts" => array(
892
+ 'jquery',
893
+ CFCORE_URL . "fields/star-rate/jquery.raty.js",
894
+ ),
895
+ "styles" => array(
896
+ //CFCORE_URL . "fields/star-rate/jquery.raty.css",
897
+ CFCORE_URL . "fields/star-rate/cf-raty.css",
898
+ )
899
+ ),
900
+ 'phone' => array(
901
+ "field" => __('Phone Number', 'caldera-forms'),
902
+ "description" => __('Phone number with masking', 'caldera-forms'),
903
+ "file" => CFCORE_PATH . "fields/phone/field.php",
904
+ "category" => __("Text Fields,Basic,User", "cladera-forms"),
905
+ "setup" => array(
906
+ "template" => CFCORE_PATH . "fields/phone/config.php",
907
+ "preview" => CFCORE_PATH . "fields/phone/preview.php",
908
+ "default" => array(
909
+ 'default' => '',
910
+ 'type' => 'local',
911
+ 'custom'=> '(999)999-9999'
912
+ ),
913
+ "scripts" => array(
914
+ CFCORE_URL . "fields/phone/masked-input.js"
915
+ )
916
+ ),
917
+ "scripts" => array(
918
+ "jquery",
919
+ CFCORE_URL . "fields/phone/masked-input.js"
920
+ )
921
+ ),
922
  'text' => array(
923
  "field" => "Single Line Text",
924
  "description" => __('Single Line Text', 'caldera-forms'),
925
  "file" => CFCORE_PATH . "fields/text/field.php",
926
  "category" => __("Text Fields,Basic", "cladera-forms"),
927
  "setup" => array(
928
+ "template" => CFCORE_PATH . "fields/text/config.php",
929
  "preview" => CFCORE_PATH . "fields/text/preview.php"
930
+ ),
931
+ "scripts" => array(
932
+ "jquery",
933
+ CFCORE_URL . "fields/phone/masked-input.js"
934
  )
935
  ),
936
  'file' => array(
937
  "field" => "File",
938
  "description" => __('File Uploader', 'caldera-forms'),
939
  "file" => CFCORE_PATH . "fields/file/field.php",
 
940
  "viewer" => array($this, 'handle_file_view'),
941
  "category" => __("Basic,File", "cladera-forms"),
942
  "setup" => array(
990
  "description" => __('Hidden', 'caldera-forms'),
991
  "file" => CFCORE_PATH . "fields/hidden/field.php",
992
  "category" => __("Text Fields,Basic", "cladera-forms"),
993
+ "static" => true,
994
  "setup" => array(
995
  "preview" => CFCORE_PATH . "fields/hidden/preview.php",
996
  "template" => CFCORE_PATH . "fields/hidden/setup.php",
1011
  "template" => CFCORE_PATH . "fields/button/config_template.html",
1012
  "preview" => CFCORE_PATH . "fields/button/preview.php",
1013
  "default" => array(
1014
+ 'class' => 'btn btn-default',
1015
  'type' => 'submit'
1016
  ),
1017
  "not_supported" => array(
1028
  "file" => CFCORE_PATH . "fields/email/field.php",
1029
  "category" => __("Text Fields,Basic", "cladera-forms"),
1030
  "setup" => array(
1031
+ "preview" => CFCORE_PATH . "fields/email/preview.php",
1032
+ "template" => CFCORE_PATH . "fields/email/config.php"
1033
  )
1034
  ),
1035
  'paragraph' => array(
1051
  "category" => __("Select Options,Special", "cladera-forms"),
1052
  "file" => CFCORE_PATH . "fields/toggle_switch/field.php",
1053
  "options" => "single",
1054
+ "static" => true,
1055
  "setup" => array(
1056
  "template" => CFCORE_PATH . "fields/toggle_switch/config_template.html",
1057
  "preview" => CFCORE_PATH . "fields/toggle_switch/preview.php",
1078
  "file" => CFCORE_PATH . "fields/dropdown/field.php",
1079
  "category" => __("Select Options,Basic", "cladera-forms"),
1080
  "options" => "single",
1081
+ "static" => true,
1082
  "setup" => array(
1083
  "template" => CFCORE_PATH . "fields/dropdown/config_template.html",
1084
  "preview" => CFCORE_PATH . "fields/dropdown/preview.php",
1096
  "file" => CFCORE_PATH . "fields/checkbox/field.php",
1097
  "category" => __("Select Options,Basic", "cladera-forms"),
1098
  "options" => "multiple",
1099
+ "static" => true,
1100
  "setup" => array(
1101
  "preview" => CFCORE_PATH . "fields/checkbox/preview.php",
1102
  "template" => CFCORE_PATH . "fields/checkbox/config_template.html",
1114
  "file" => CFCORE_PATH . "fields/radio/field.php",
1115
  "category" => __("Select Options,Basic", "cladera-forms"),
1116
  "options" => true,
1117
+ "static" => true,
1118
  "setup" => array(
1119
  "preview" => CFCORE_PATH . "fields/radio/preview.php",
1120
  "template" => CFCORE_PATH . "fields/radio/config_template.html",
1186
 
1187
  }
1188
 
1189
+ static public function check_condition($conditions, $form){
1190
 
1191
  $trues = array();
1192
  if(empty($conditions['group'])){
1193
  return true;
1194
  }
1195
+ //$data = self::get_submission_data($form);
1196
+
1197
  foreach($conditions['group'] as $groupid=>$lines){
1198
  $truelines = array();
1199
 
1200
  foreach($lines as $lineid=>$line){
 
1201
 
1202
+ $value = (array) self::get_field_data($line['field'], $form);
1203
+ if(empty($value)){
1204
+ $value = array('');
1205
+ }
1206
+ // do field value replaces
1207
+ if( false !== strpos($line['value'], '%')){
1208
+ $isslug = self::get_slug_data( trim($line['value'], '%'), $form);
1209
+ if( $isslug !== null ){
1210
+ $line['value'] = $isslug;
1211
  }
1212
+ }
1213
+
1214
 
1215
+ $truelines[$lineid] = false;
 
 
 
 
 
 
 
 
1216
 
1217
+ switch ($line['compare']) {
1218
+ case 'is':
1219
+ if(is_array($value)){
1220
+ if(in_array($line['value'], $value)){
1221
+ $truelines[$lineid] = true;
1222
+ }
1223
+ }else{
1224
+ if($value == $line['value']){
1225
+ $truelines[$lineid] = true;
1226
+ }
1227
+ }
1228
+ break;
1229
+ case 'isnot':
1230
+ if(is_array($value)){
1231
+ if(!in_array($line['value'], $value)){
1232
+ $truelines[$lineid] = true;
1233
+ }
1234
+ }else{
1235
+ if($value != $line['value']){
1236
+ $truelines[$lineid] = true;
1237
+ }
1238
+ }
1239
+ break;
1240
+ case '>':
1241
+ if(is_array($value)){
1242
+ if(array_sum($value) > $line['value']){
1243
+ $truelines[$lineid] = true;
1244
+ }
1245
+ }else{
1246
+ if($value > $line['value']){
1247
+ $truelines[$lineid] = true;
1248
+ }
1249
+ }
1250
+ break;
1251
+ case '<':
1252
+ if(is_array($value)){
1253
+ if(array_sum($value) < $line['value']){
1254
+ $truelines[$lineid] = true;
1255
+ }
1256
+ }else{
1257
+ if($value < $line['value']){
1258
+ $truelines[$lineid] = true;
1259
+ }
1260
+ }
1261
+ break;
1262
+ case 'startswith':
1263
+ if(is_array($value)){
1264
+ foreach($value as $part){
1265
+ if( 0 === strpos($line['value'], $part)){
1266
  $truelines[$lineid] = true;
1267
  }
1268
+ }
1269
+ }else{
1270
+ if( substr( $value, 0, strlen($line['value']) ) == $line['value']){
1271
+ $truelines[$lineid] = true;
1272
+ }
1273
+ }
1274
+ break;
1275
+ case 'endswith':
1276
+ if(is_array($value)){
1277
+ foreach($value as $part){
1278
+ if( substr( $part, strlen($part)-strlen($line['value']) ) == $line['value']){
1279
  $truelines[$lineid] = true;
1280
  }
1281
+ }
1282
+ }else{
1283
+ if( substr( $value, strlen($value)-strlen($line['value']) ) == $line['value']){
1284
+ $truelines[$lineid] = true;
1285
+ }
1286
  }
1287
+ break;
1288
+ case 'contains':
1289
+ if(is_array($value)){
1290
+ if( false !== strpos( implode('', $value), $line['value'] ) ){
1291
+ $truelines[$lineid] = true;
1292
+ }
1293
+ }else{
1294
+ if( false !== strpos( $value, $line['value'] ) ){
1295
+ $truelines[$lineid] = true;
1296
+ }
1297
+ }
1298
+ break;
1299
  }
1300
+
1301
  }
1302
 
1303
  $trues[$groupid] = in_array(false, $truelines) ? false : true;
1304
  }
1305
+
1306
  if($conditions['type'] == 'use' || $conditions['type'] == 'show'){
1307
  if(in_array(true, $trues)){
1308
  return true;
1318
  }
1319
 
1320
  // FRONT END STUFFF
1321
+ static public function form_redirect($type, $url, $form, $processid){
1322
 
1323
+ $url = apply_filters('caldera_forms_redirect_url', $url, $form, $processid);
1324
+ $url = apply_filters('caldera_forms_redirect_url_' . $type, $url, $form, $processid);
 
 
 
1325
 
1326
+ do_action('caldera_forms_redirect', $type, $url, $form, $processid);
1327
+ do_action('caldera_forms_redirect_' . $type, $url, $form, $processid);
1328
+
1329
  if(!empty($url)){
1330
  wp_redirect( $url );
1331
  exit;
1332
  }
1333
  }
1334
+ // magic tags
1335
+
1336
+ // set tags
1337
+ public function set_magic_tags($tags){
1338
+
1339
+ // get internal tags
1340
+ $system_tags = array(
1341
+ 'ip',
1342
+ 'user:id',
1343
+ 'user:user_login',
1344
+ 'user:firstname',
1345
+ 'user:lastname',
1346
+ 'user:user_email' => array(
1347
+ 'text',
1348
+ 'email'
1349
+ ),
1350
+ 'embed_post:ID',
1351
+ 'embed_post:post_title',
1352
+ 'embed_post:permalink',
1353
+ 'embed_post:post_date' => array(
1354
+ 'text',
1355
+ 'date_picker'
1356
+ ),
1357
+ 'date:Y-m-d H:i:s' => array(
1358
+ 'text',
1359
+ 'date_picker'
1360
+ ),
1361
+ 'date:Y/m/d',
1362
+ 'date:Y/d/m'
1363
+
1364
+ );
1365
+
1366
+ $tags['system'] = array(
1367
+ 'type' => __('System Tags', 'caldera-forms'),
1368
+ 'tags' => $system_tags
1369
+ );
1370
+ // get processor tags
1371
+ $processors = apply_filters('caldera_forms_get_form_processors', array() );
1372
+ if(!empty($processors)){
1373
+ foreach($processors as $processor_key=>$processor){
1374
+ if(isset($processor['magic_tags'])){
1375
+ foreach($processor['magic_tags'] as $key_tag=>$value_tag){
1376
+
1377
+ if(!isset($tags[$processor_key])){
1378
+ $tags[$processor_key] = array(
1379
+ 'type' => $processor['name'],
1380
+ 'tags' => array()
1381
+ );
1382
+ }
1383
+ if(is_array($value_tag)){
1384
+
1385
+ // compatibility specific
1386
+ $tag = $processor_key.':'.$key_tag;
1387
+ if(!isset($tags[$processor_key]['tags'][$tag])){
1388
+ if(!in_array('text', $value_tag)){
1389
+ $value_tag[] = 'text';
1390
+ }
1391
+ $tags[$processor_key]['tags'][$tag] = $value_tag;
1392
+ }
1393
+ }else{
1394
+ // compatibility text
1395
+ $tag = $processor_key.':'.$value_tag;
1396
+ if(!in_array($tag, $tags)){
1397
+ $tags[$processor_key]['tags'][] = $tag;
1398
+ }
1399
+
1400
+ }
1401
+ }
1402
+ }
1403
+ }
1404
+ }
1405
+
1406
+ return $tags;
1407
+ }
1408
+
1409
+ static public function do_magic_tags($value){
1410
+
1411
+ global $processed_meta, $form;
1412
+ /// get meta entry for magic tags defined.
1413
+
1414
+ // check for magics
1415
+ preg_match_all("/\{(.+?)\}/", $value, $magics);
1416
+ if(!empty($magics[1])){
1417
+ foreach($magics[1] as $magic_key=>$magic_tag){
1418
+
1419
+ $magic = explode(':', $magic_tag, 2);
1420
+
1421
+ if(count($magic) == 2){
1422
+ switch (strtolower( $magic[0]) ) {
1423
+ case 'get':
1424
+ if( isset($_GET[$magic[1]])){
1425
+ $magic_tag = $_GET[$magic[1]];
1426
+ }else{
1427
+ $magic_tag = null;
1428
+ }
1429
+ break;
1430
+ case 'post':
1431
+ if( isset($_POST[$magic[1]])){
1432
+ $magic_tag = $_POST[$magic[1]];
1433
+ }else{
1434
+ $magic_tag = null;
1435
+ }
1436
+ break;
1437
+ case 'request':
1438
+ if( isset($_REQUEST[$magic[1]])){
1439
+ $magic_tag = $_REQUEST[$magic[1]];
1440
+ }else{
1441
+ $magic_tag = null;
1442
+ }
1443
+ break;
1444
+ case 'date':
1445
+ $magic_tag = date($magic[1]);
1446
+ break;
1447
+ case 'user':
1448
+ if(is_user_logged_in()){
1449
+ $user = get_userdata( get_current_user_id() );
1450
+ if(isset( $user->data->{$magic[1]} )){
1451
+ $magic_tag = $user->data->{$magic[1]};
1452
+ }else{
1453
+ if(strtolower($magic[1]) == 'id'){
1454
+ $magic_tag = $user->ID;
1455
+ }else{
1456
+ $magic_tag = get_user_meta( $user->ID, $magic[1], true );
1457
+ }
1458
+ }
1459
+ }else{
1460
+ $magic_tag = null;
1461
+ }
1462
+ break;
1463
+ case 'embed_post':
1464
+ global $post;
1465
+
1466
+ if(is_object($post)){
1467
+ if(isset( $post->{$magic[1]} )){
1468
+ $magic_tag = $post->{$magic[1]};
1469
+ }else{
1470
+
1471
+ // extra post data
1472
+ switch ($magic[1]) {
1473
+ case 'permalink':
1474
+ $magic_tag = get_permalink( $post->ID );
1475
+ break;
1476
+
1477
+ }
1478
+
1479
+ }
1480
+ }else{
1481
+ $magic_tag = null;
1482
+ }
1483
+ break;
1484
+ case 'post_meta':
1485
+ global $post;
1486
+
1487
+ if(is_object($post)){
1488
+ $post_metavalue = get_post_meta( $post->ID, $magic[1] );
1489
+ if( false !== strpos($magic[1], ':') ){
1490
+ $magic[3] = explode(':', $magic[1]);
1491
+ }
1492
+ if(empty($post_metavalue)){
1493
+ $magic_tag = null;
1494
+ }else{
1495
+ if(empty($magic[3])){
1496
+ $magic_tag = implode(', ', $post_metavalue);
1497
+ }else{
1498
+ $outmagic = array();
1499
+ foreach ($magic[3] as $subkey => $subvalue) {
1500
+ foreach( (array) $post_metavalue as $subsubkey=>$subsubval){
1501
+ if(isset($subsubval[$subvalue])){
1502
+ $outmagic[] = $post_metavalue;
1503
+ }
1504
+ }
1505
+ }
1506
+ $magic_tag = implode(', ', $outmagic);
1507
+ }
1508
+ }
1509
+ }else{
1510
+ $magic_tag = null;
1511
+ }
1512
+ break;
1513
+
1514
+ }
1515
+ }else{
1516
+ switch ($magic_tag) {
1517
+ case 'ip':
1518
+ $magic_tag = $_SERVER['REMOTE_ADDR'];
1519
+ break;
1520
+ case 'summary':
1521
+ if(!empty($form['fields'])){
1522
+ $out = array();
1523
+ foreach($form['fields'] as $field_id=>$field){
1524
+ $field_value = self::get_field_data($field_id, $form);
1525
+ if(is_array($field_value)){
1526
+ $field_value = implode(', ', $field_value);
1527
+ }
1528
+ if($field_value !== null && strlen($field_value) > 0){
1529
+ $out[] = $field['label'].': '.$field_value;
1530
+ }
1531
+ }
1532
+ if(!empty($out)){
1533
+ $magic_tag = implode("\r\n", $out);
1534
+ }
1535
+ }
1536
+ break;
1537
+ }
1538
+ }
1539
+
1540
+ $filter_value = apply_filters('caldera_forms_do_magic_tag', $magic_tag, $magics[0][$magic_key]);
1541
+ if(!empty($form['ID']) ){
1542
+ //dump($processed_meta[$form['ID']]);
1543
+
1544
+ // check if its a process id or processor slug
1545
+ if( empty($processed_meta[$form['ID']][$magic[0]]) && !empty($form['processors']) ){
1546
+
1547
+ // if not a direct chec if theres a slug
1548
+ foreach( $form['processors'] as $processid => $processor){
1549
+ if($processor['type'] === $magic[0]){
1550
+ if(!empty($processed_meta[$form['ID']][$processid])){
1551
+ $magic[0] = $processid;
1552
+ break;
1553
+ }
1554
+ }
1555
+ }
1556
+ }
1557
+ if(!empty($processed_meta[$form['ID']][$magic[0]])){
1558
+
1559
+ if(isset( $processed_meta[$form['ID']][$magic[0]][$magic[1]] ) ){
1560
+ // direct fined
1561
+ $filter_value = implode(', ', (array) $processed_meta[$form['ID']][$magic[0]][$magic[1]] );
1562
+ }else{
1563
+ foreach($processed_meta[$form['ID']][$magic[0]] as $return_array){
1564
+ foreach($return_array as $return_line){
1565
+ if(isset($return_line[$magic[1]])){
1566
+ $filter_value = $return_line[$magic[1]];
1567
+ }
1568
+ }
1569
+ }
1570
+ }
1571
+ }
1572
+ }
1573
+
1574
+ $value = str_replace($magics[0][$magic_key], $filter_value, $value);
1575
+ if( $magics[1][$magic_key] === $value){
1576
+ // return to normal
1577
+ $value = $magics[0][$magic_key];
1578
+ }
1579
+ }
1580
+ }
1581
+ return $value;
1582
+ }
1583
+
1584
+ // get field types.
1585
+ static public function get_field_types(){
1586
+ //global $field_types;
1587
+ //if(!empty($field_types)){
1588
+ // return $field_types;
1589
+ //}
1590
+
1591
+
1592
+ $field_types = apply_filters('caldera_forms_get_field_types', array() );
1593
+
1594
+ if(!empty($field_types)){
1595
+ foreach($field_types as $fieldType=>$fieldConfig){
1596
+ // check for a viewer
1597
+ if(isset($fieldConfig['viewer'])){
1598
+ add_filter('caldera_forms_view_field_' . $fieldType, $fieldConfig['viewer'], 10, 3);
1599
+ }
1600
+ }
1601
+ }
1602
+
1603
+ return $field_types;
1604
+ }
1605
+
1606
+ static public function get_processor_by_type($type, $form){
1607
+ if(is_string($form)){
1608
+ $form = get_option($form);
1609
+ if(!empty($form['ID'])){
1610
+ if($form['ID'] !== $form || empty($form['processors'])){
1611
+ return false;
1612
+ }
1613
+ }
1614
+ }
1615
+
1616
+ if(!empty($form['processors'])){
1617
+ $processors = array();
1618
+ foreach($form['processors'] as $processor){
1619
+ if($processor['type'] == $type){
1620
+ $processors[] = $processor;
1621
+ }
1622
+ }
1623
+ if(empty($processors)){
1624
+ return false;
1625
+ }
1626
+ return $processors;
1627
+ }
1628
+ return false;
1629
+ }
1630
+
1631
+ static public function set_submission_meta($key, $value, $form, $processor_id='meta'){
1632
+ global $processed_meta;
1633
+
1634
+ if(is_string($form)){
1635
+ $form['ID'] = $form;
1636
+ }
1637
+
1638
+ // set value
1639
+ if(isset($form['ID'])){
1640
+ if(isset($processed_meta[$form['ID']][$processor_id][$key])){
1641
+ if(in_array($value, $processed_meta[$form['ID']][$processor_id][$key])){
1642
+ return true;
1643
+ }
1644
+ }
1645
+ $processed_meta[$form['ID']][$processor_id][$key][] = $value;
1646
+ return true;
1647
+ }
1648
+ }
1649
+
1650
+ static public function set_field_data($field_id, $data, $form, $entry_id = false){
1651
+ global $processed_data;
1652
+
1653
+ $current_data = self::get_field_data($field_id, $form, $entry_id);
1654
+
1655
+ if(is_string($form)){
1656
+ // get processed cached item using the form id
1657
+ if(isset($processed_data[$form][$field_id])){
1658
+ $processed_data[$form][$field_id] = $data;
1659
+ return true;
1660
+ }
1661
+ }
1662
+ // form object
1663
+ if(isset($form['ID'])){
1664
+ if(isset($processed_data[$form['ID']][$field_id])){
1665
+ $processed_data[$form['ID']][$field_id] = $data;
1666
+ return true;
1667
+ }
1668
+ }
1669
+ }
1670
+
1671
+ static public function get_field_data($field_id, $form, $entry_id = false){
1672
+ global $processed_data;
1673
+
1674
+ //dump($processed_data[$form['ID']],0);
1675
+ //echo $field_id.'<br>';
1676
+ if(is_string($form)){
1677
+ // get processed cached item using the form id
1678
+ if(isset($processed_data[$form][$field_id])){
1679
+ return $processed_data[$form][$field_id];
1680
+ }
1681
+
1682
+ $form = get_option( $form );
1683
+ if(!isset($form['ID']) || $form['ID'] !== $form){
1684
+
1685
+ return null;
1686
+ }
1687
+ }
1688
+ // get processed cached item
1689
+ if(isset($processed_data[$form['ID']][$field_id])){
1690
+ return $processed_data[$form['ID']][$field_id];
1691
+ }
1692
+ // entry fetch
1693
+ if(!empty($entry_id) && isset($form['fields'][$field_id])){
1694
+
1695
+ global $wpdb;
1696
+
1697
+ $entry = $wpdb->get_results($wpdb->prepare("
1698
+ SELECT `value` FROM `" . $wpdb->prefix ."cf_form_entry_values` WHERE `entry_id` = %d AND `field_id` = %s AND `slug` = %s", $entry_id, $field_id, $form['fields'][$field_id]['slug']), ARRAY_A);
1699
+
1700
+ if(!empty($entry)){
1701
+ if( count( $entry ) > 1){
1702
+ $out = array();
1703
+ foreach($entry as $item){
1704
+ $out[] = $item['value'];
1705
+ }
1706
+ $processed_data[$form['ID']][$field_id] = $out;
1707
+ }else{
1708
+ $processed_data[$form['ID']][$field_id] = $entry[0]['value'];
1709
+ }
1710
+ }else{
1711
+ $processed_data[$form['ID']][$field_id] = null;
1712
+ }
1713
+ return $processed_data[$form['ID']][$field_id];
1714
+ //return $processed_data[$form['ID']][$field_id] = ;
1715
+ }
1716
+
1717
+ if(isset($form['fields'][$field_id])){
1718
+ // get field
1719
+ $field = apply_filters('caldera_forms_render_setup_field', $form['fields'][$field_id], $form);
1720
+
1721
+ if(empty($field) || !isset($field['ID'])){
1722
+ return null;
1723
+ }
1724
+ // get field types
1725
+ $field_types = self::get_field_types();
1726
+
1727
+ if(!isset($field_types[$field['type']])){
1728
+ return null;
1729
+ }
1730
+ $entry = null;
1731
+ // dont bother if conditions say it shouldnt be here.
1732
+ if(!empty($field['conditions']['type'])){
1733
+ if(!self::check_condition($field['conditions'], $form)){
1734
+ $processed_data[$form['ID']][$field_id] = $entry;
1735
+ return $entry;
1736
+ }
1737
+ }
1738
+
1739
+ // check condition to see if field should be there first.
1740
+ // check if conditions match first. ignore vailators if not part of condition
1741
+ if(isset($_POST[$field_id])){
1742
+ $entry = stripslashes_deep($_POST[$field_id]);
1743
+ }
1744
+ // apply field filter
1745
+ if(has_filter('caldera_forms_process_field_' . $field['type'])){
1746
+ $entry = apply_filters( 'caldera_forms_process_field_' . $field['type'] , $entry, $field, $form );
1747
+ if( is_wp_error( $entry ) ) {
1748
+ $processed_data[$form['ID']][$field_id] = $entry;
1749
+ return $entry;
1750
+ }
1751
+ }
1752
+
1753
+ if(is_string( $entry ) && strlen( $entry ) <= 0){
1754
+ $entry = null;
1755
+ }
1756
+ // is static
1757
+ if(!empty($field_types[$field['type']]['static'])){
1758
+ // is options or not
1759
+
1760
+ $field = apply_filters('caldera_forms_render_get_field', $field, $form);
1761
+ $field = apply_filters('caldera_forms_render_get_field_type-' . $field['type'], $field, $form);
1762
+ $field = apply_filters('caldera_forms_render_get_field_slug-' . $field['slug'], $field, $form);
1763
+
1764
+ if(!empty($field_types[$field['type']]['options'])){
1765
+ if(is_array($entry)){
1766
+ $out = array();
1767
+ foreach($entry as $option_id=>$option){
1768
+ if(isset($field['config']['option'][$option_id])){
1769
+ if(!isset($field['config']['option'][$option_id]['value'])){
1770
+ $field['config']['option'][$option_id]['value'] = $field['config']['option'][$option_id]['label'];
1771
+ }
1772
+ $out[] = self::do_magic_tags($field['config']['option'][$option_id]['value']);
1773
+ }
1774
+ }
1775
+ $processed_data[$form['ID']][$field_id] = $out;
1776
+ }else{
1777
+ if(!empty($field['config']['option'])){
1778
+ foreach($field['config']['option'] as $option){
1779
+ if($option['value'] == $entry){
1780
+ $processed_data[$form['ID']][$field_id] = self::do_magic_tags($entry);
1781
+ break;
1782
+ }
1783
+ }
1784
+ }
1785
+ }
1786
+ }else{
1787
+ $processed_data[$form['ID']][$field_id] = self::do_magic_tags($field['config']['default']);
1788
+ }
1789
+ }else{
1790
+ // dynamic
1791
+ $processed_data[$form['ID']][$field_id] = $entry;
1792
+ }
1793
+ }else{
1794
+ $is_tag = self::do_magic_tags($field_id);
1795
+ if($is_tag !== $field_id){
1796
+ $processed_data[$form['ID']][$field_id] = $is_tag;
1797
+ }
1798
+ }
1799
+
1800
+ if(isset($processed_data[$form['ID']][$field_id])){
1801
+ return $processed_data[$form['ID']][$field_id];
1802
+ }
1803
+
1804
+
1805
+ return null;
1806
+ }
1807
+ static public function get_slug_data($slug, $form, $entry_id = false){
1808
+
1809
+
1810
+ $out = array();
1811
+ if(false !== strpos($slug, '.')){
1812
+ $slug_parts = explode('.', $slug);
1813
+ $slug = array_shift($slug_parts);
1814
+ }
1815
+
1816
+ $field_types = self::get_field_types();
1817
+
1818
+ foreach($form['fields'] as $field_id=>$field){
1819
+
1820
+ if($field['slug'] == $slug){
1821
+
1822
+ if(isset($_POST[$field_id])){
1823
+ if(!empty($slug_parts)){
1824
+ // just the part
1825
+ $line = stripslashes_deep( $_POST[$field_id] );
1826
+ foreach($slug_parts as $part){
1827
+ if(isset($line[$part])){
1828
+ $line = $line[$part];
1829
+ }
1830
+ }
1831
+ $out[] = $line;
1832
+ }else{
1833
+ //the whole thing
1834
+ $entry = stripslashes_deep( $_POST[$field_id] );
1835
+
1836
+ //$entry = apply_filters('caldera_forms_view_field_' . $field['type'], $entry, $field, $form);
1837
+
1838
+ /*if(isset($field_types[$field['type']]['viewer'])){
1839
+
1840
+ if(is_array($field_types[$field['type']]['viewer'])){
1841
+ $entry = call_user_func_array($field_types[$field['type']]['viewer'],array($entry, $field, $form));
1842
+ }else{
1843
+ if(function_exists($field_types[$field['type']]['viewer'])){
1844
+ $func = $field_types[$field['type']]['viewer'];
1845
+ $entry = $func($entry, $field, $form);
1846
+ }
1847
+ }
1848
+ }*/
1849
+ if(is_array($entry)){
1850
+ if(isset($entry[0])){
1851
+ // list
1852
+ $entry = $field['label'].': '. implode(',' , $entry);
1853
+ }else{
1854
+ // named
1855
+ foreach($entry as $item_key=>$item){
1856
+ if(is_array($item)){
1857
+ $item = $item_key.' ('.implode(', ', $item).')';
1858
+ }
1859
+ $out[] = $item;
1860
+ }
1861
+ }
1862
+ }else{
1863
+ $out[] = $entry;
1864
+ }
1865
+ }
1866
+ }
1867
+ }
1868
+ }
1869
+ if(count($out) === 1){
1870
+ $out = array_shift($out);
1871
+ }
1872
+ return $out;
1873
+ }
1874
+ static public function get_entry_detail($entry_id, $form){
1875
+ global $wpdb;
1876
+
1877
+ $entry = $wpdb->get_row($wpdb->prepare("SELECT * FROM `" . $wpdb->prefix ."cf_form_entries` WHERE `id` = %d", $entry_id), ARRAY_A);
1878
+ if(!empty($entry)){
1879
+ // get meta if any
1880
+ $entry_meta = $wpdb->get_results($wpdb->prepare("SELECT * FROM `" . $wpdb->prefix ."cf_form_entry_meta` WHERE `entry_id` = %d", $entry_id), ARRAY_A);
1881
+ if(!empty($entry_meta)){
1882
+ $processors = apply_filters('caldera_forms_get_form_processors', array() );
1883
+ $entry['meta'] = array();
1884
+ foreach($entry_meta as $meta_index=>$meta){
1885
+ // is json?
1886
+ if( false !== strpos($meta['meta_value'], '{') || false !== strpos($meta['meta_value'], '[') ){
1887
+ $meta['meta_value'] = json_decode($meta['meta_value'], ARRAY_A);
1888
+ }else{
1889
+ $meta['meta_value'] = $meta['meta_value'];
1890
+ }
1891
+
1892
+ $group = 'meta';
1893
+ $meta = apply_filters('caldera_forms_get_entry_meta', $meta, $form);
1894
+
1895
+ if(isset($form['processors'][$meta['process_id']])){
1896
+
1897
+ $process_config = array();
1898
+ if(isset($form['processors'][$meta['process_id']]['config'])){
1899
+ $process_config = $form['processors'][$meta['process_id']]['config'];
1900
+ }
1901
+
1902
+ $group = $form['processors'][$meta['process_id']]['type'];
1903
+ $meta = apply_filters('caldera_forms_get_entry_meta_' . $form['processors'][$meta['process_id']]['type'], $meta, $process_config , $form);
1904
+
1905
+
1906
+ // allows plugins to remove it.
1907
+ if(!empty($meta)){
1908
+ if(!isset($entry['meta'][$group])){
1909
+ // is processor
1910
+ if(isset($form['processors'][$meta['process_id']]['type'])){
1911
+ $meta_name = $processors[$form['processors'][$meta['process_id']]['type']]['name'];
1912
+ }else{
1913
+ $meta_name = $meta['process_id'];
1914
+ }
1915
+ $entry['meta'][$group] = array(
1916
+ 'name' => $meta_name,
1917
+ 'data' => array()
1918
+ );
1919
+ // custom template
1920
+ if( isset( $processors[$form['processors'][$meta['process_id']]['type']]['meta_template'] ) && file_exists( $processors[$form['processors'][$meta['process_id']]['type']]['meta_template'] ) ){
1921
+ $entry['meta'][$group][$group.'_template'] = $entry['meta'][$group]['template'] = true;
1922
+ }
1923
+ }
1924
+
1925
+ //if(!empty($meta['meta_title'])){
1926
+ // $entry['meta'][$group]['data'][$meta['process_id']]['title'] = $meta['meta_title'];
1927
+ //}
1928
+
1929
+ $entry['meta'][$group]['data'][$meta['process_id']]['entry'][] = $meta;
1930
+
1931
+
1932
+ /*if(is_array($meta['meta_value'])){
1933
+ foreach($meta['meta_value'] as $mkey=>$mval){
1934
+ $entry['meta'][$group]['data'][$meta['process_id']]['title'] = $meta['meta_key'];
1935
+ $entry['meta'][$group]['data'][$meta['process_id']]['entry'][] = array(
1936
+ 'meta_key' => $mkey,
1937
+ 'meta_value' => $mval
1938
+ );
1939
+ }
1940
+ }else{
1941
+ $entry['meta'][$group]['data'][$meta['process_id']]['entry'][] = array(
1942
+ 'meta_key' => $meta['meta_key'],
1943
+ 'meta_value' => $meta['meta_value']
1944
+ );
1945
+ }*/
1946
+
1947
+ }
1948
+ }
1949
+ }
1950
+ }
1951
+ }
1952
+ $entry = apply_filters( 'caldera_forms_get_entry_detail', $entry, $entry_id, $form );
1953
+ return $entry;
1954
+ }
1955
+
1956
+ static public function get_submission_data($form, $entry_id = false){
1957
+ global $processed_data;
1958
+
1959
+ if(is_string($form)){
1960
+ // get processed cached item using the form id
1961
+ if(isset($processed_data[$form])){
1962
+ return $processed_data[$form];
1963
+ }
1964
+ $form_id = $form;
1965
+ $form = get_option( $form );
1966
+ if(!isset($form['ID']) || $form['ID'] !== $form_id){
1967
+ return new WP_Error( 'fail', __('Invalid form ID') );
1968
+ }
1969
+ }
1970
+
1971
+
1972
+ // initialize process data
1973
+ foreach($form['fields'] as $field_id=>$field){
1974
+ self::get_field_data( $field_id, $form, $entry_id);
1975
+ }
1976
+
1977
+ return $processed_data[$form['ID']];
1978
+ }
1979
 
1980
  static public function process_submission(){
1981
+ global $post;
1982
+ global $front_templates;
1983
+ global $process_id;
1984
+ global $form;
1985
+ global $field_types;
1986
+ global $rawdata;
1987
+ global $processed_data;
1988
+ global $transdata;
1989
+
1990
 
1991
+
1992
+ // clean out referrer
1993
+ if(empty($_POST['_wp_http_referer_true'])){
1994
+ $_POST['_wp_http_referer_true'] = $_SERVER['HTTP_REFERER'];
1995
+ }
1996
+
1997
+ $referrer = parse_url( $_POST['_wp_http_referer_true'] );
1998
  if(!empty($referrer['query'])){
1999
  parse_str($referrer['query'], $referrer['query']);
2000
  if(isset($referrer['query']['cf_er'])){
2004
  unset($referrer['query']['cf_su']);
2005
  }
2006
  }
2007
+ // get form and check
2008
  $form = get_option( $_POST['_cf_frm_id'] );
2009
  if(empty($form['ID']) || $form['ID'] != $_POST['_cf_frm_id']){
2010
  return;
2011
  }
2012
+ // init filter
2013
+ $form = apply_filters('caldera_forms_submit_get_form', $form);
2014
 
2015
+ // instance number
 
 
 
 
 
2016
  $form_instance_number = 1;
2017
  if(isset($_POST['_cf_frm_ct'])){
2018
  $form_instance_number = $_POST['_cf_frm_ct'];
2019
  }
2020
 
2021
+ // get all fieldtype
2022
+ $field_types = self::get_field_types();
2023
 
2024
+ // setup fieldtypes field submissions
2025
+ if(!empty($field_types)){
2026
+ foreach($field_types as $fieldType=>$fieldConfig){
2027
+ // check for a handler
2028
+ if(isset($fieldConfig['handler'])){
2029
+ add_filter('caldera_forms_process_field_' . $fieldType, $fieldConfig['handler'], 10, 3);
2030
+ }
2031
+ // check for a hash
2032
+ if(isset($fieldConfig['save'])){
2033
+ add_filter('caldera_forms_save_field_' . $fieldType, $fieldConfig['save'], 10, 3);
2034
+ }
2035
+ // check for a hash
2036
+ if(isset($fieldConfig['validate'])){
2037
+ add_filter('caldera_forms_validate_field_' . $fieldType, $fieldConfig['validate'], 10, 3);
2038
+ }
2039
+ }
2040
+ }
2041
+
2042
  // SET process ID
2043
+ if(isset($_GET['cf_er'])){
2044
+ $_POST['_cf_frm_tr'] = $_GET['cf_er'];
2045
+ }
2046
 
 
 
 
 
 
 
 
 
 
2047
 
2048
+ if(isset($_POST['_cf_frm_tr'])){
2049
+ $pretransient = get_transient( $_POST['_cf_frm_tr'] );
2050
+ if( !empty( $pretransient['transient'] ) && $pretransient['transient'] === $_POST['_cf_frm_tr']){
2051
+ $transdata = $pretransient;
2052
+ $process_id = $transdata['transient'];
2053
+ // unset error details
2054
+ if(isset($transdata['type'])){
2055
+ unset( $transdata['type'] );
2056
+ }
2057
+ if(isset($transdata['note'])){
2058
+ unset( $transdata['note'] );
2059
+ }
2060
+ if(isset($transdata['error'])){
2061
+ unset( $transdata['error'] );
2062
+ }
2063
+ if(isset($transdata['fields'])){
2064
+ unset( $transdata['fields'] );
2065
+ }
2066
+
2067
+ }
2068
+ }
2069
+ if(empty($process_id)){
2070
+ $process_id = uniqid('_cf_process_');
2071
+ }
2072
 
 
 
2073
 
2074
  // start action
2075
+ do_action('caldera_forms_submit_start', $form);
2076
 
2077
+ // initialize data
2078
+ $entry_id = false;
2079
+ if(isset($_POST['_cf_frm_edt'])){
2080
+ $entry_id = (int) $_POST['_cf_frm_edt'];
2081
+ }
2082
+ // dont get data with ID else update wont work. since it will update the same thing
2083
+ //$data = self::get_submission_data($form, $entry_id);
2084
+ $data = self::get_submission_data($form);
2085
+ //dump($data);
2086
  // requireds
2087
  // set transient for returns submittions
2088
+ if(empty($transdata)){
2089
+ $transdata = array(
2090
+ 'transient' => $process_id,
2091
+ 'form_instance' => $form_instance_number,
2092
+ 'expire' => 120,
2093
+ 'data' => array_merge($_POST, $data),
2094
+ );
2095
+ }
2096
+ // remove AJAX value for tp_
2097
+ if(isset($transdata['data']['cfajax'])){
2098
+ unset($transdata['data']['cfajax']);
2099
+ }
2100
+ // setup transient data
2101
+ $transdata = apply_filters('caldera_forms_submit_transient_setup', $transdata);
2102
 
2103
  // setup processor bound requieds
2104
  if(!empty($form['processors'])){
2105
  $bound_fields = array();
2106
  foreach($form['processors'] as $processor_id=>$processor){
2107
+
2108
+ if(!empty($processor['config']['_required_bounds'])){
2109
  foreach($processor['config'] as $slug=>&$value){
2110
+ if($slug == '_required_bounds'){
2111
+ continue;
2112
+ }
2113
+
2114
+ if(in_array($slug, $processor['config']['_required_bounds'])){
2115
+ if(isset($form['fields'][$value])){
2116
+ if(!isset($process_data[$value])){
2117
+ $form['fields'][$value]['required'] = 1;
2118
+ }
2119
+ }
2120
+ }
2121
  }
2122
  }
2123
  }
 
 
 
2124
  }
2125
 
2126
+ // check submit type (new or update)
2127
+ if(isset($_POST['_cf_frm_edt'])){
2128
+ // is edit
2129
+ //check user can edit this item.
2130
+ $user_id = get_current_user_id();
2131
+ if(empty($user_id)){
2132
+ $transdata['error'] = true;
2133
+ $transdata['note'] = __('Permission denied or entry does not exist.', 'caldera-forms');
2134
+ }else{
2135
+
2136
+ $details = self::get_entry_detail($_POST['_cf_frm_edt'], $form);
2137
+ if(empty($details)){
2138
+ $transdata['error'] = true;
2139
+ $transdata['note'] = __('Permission denied or entry does not exist.', 'caldera-forms');
2140
  }else{
2141
+ // check user can edit
2142
+ if( current_user_can( 'edit_posts' ) || $details['user_id'] === $user_id ){
2143
+ // can edit.
2144
+ }else{
2145
+ $transdata['error'] = true;
2146
+ $transdata['note'] = __('Permission denied or entry does not exist.', 'caldera-forms');
2147
  }
2148
  }
2149
+
 
 
2150
  }
2151
 
2152
+ }
 
 
 
 
 
 
 
 
 
2153
 
2154
 
2155
+ // start brining in entries
2156
+ foreach($form['fields'] as $field_id=>$field){
2157
+
2158
+ $entry = self::get_field_data($field_id, $form);
2159
+
2160
+ if ( is_wp_error( $entry )){
2161
+ $transdata['fields'][$field_id] = $entry->get_error_message();
2162
+ }else{
2163
+ // required check
2164
+ $failed = false;
2165
+ // run validators
2166
+ if(has_filter('caldera_forms_validate_field_' . $field['type'])){
2167
+ $entry = apply_filters( 'caldera_forms_validate_field_' . $field['type'], $entry, $field, $form );
2168
+ }
2169
+ // if required, check the validators returned errors or not.
2170
+ if(!empty($field['required'])){
2171
+
2172
+ // check if conditions match first. ignore vailators if not part of condition
2173
+ if(!empty($field['conditions']['type'])){
2174
+ if(!self::check_condition($field['conditions'], $form)){
2175
+ continue;
2176
  }
 
 
 
 
2177
  }
2178
+ // if error - return so
2179
+ if ( is_wp_error( $entry )){
2180
+ $transdata['fields'][$field_id] = $entry->get_error_message();
2181
+ }elseif($entry === null){
2182
+ $transdata['fields'][$field_id] = $field['slug'] .' ' .__('is required', 'caldera-forms');
2183
+ }
2184
  }
2185
  }
2186
 
2187
  }
2188
 
2189
  // check requireds
2190
+ if(!empty($transdata['fields']) || !empty($transdata['error'])){
2191
  $transdata['type'] = 'error';
2192
  // set error transient
2193
+ $transdata = apply_filters('caldera_forms_submit_return_transient', $transdata, $form, $referrer, $process_id);
2194
+ $transdata = apply_filters('caldera_forms_submit_return_transient_required', $transdata, $form, $referrer, $process_id);
2195
+
 
 
2196
  // back to form
2197
  $query_str = array(
2198
+ 'cf_er' => $process_id
2199
  );
2200
  if(!empty($referrer['query'])){
2201
  $query_str = array_merge($referrer['query'], $query_str);
2202
  }
2203
  $referrer = $referrer['path'] . '?' . http_build_query($query_str);
2204
+ $referrer = apply_filters('caldera_forms_submit_return_redirect', $referrer, $form, $process_id);
2205
+ $referrer = apply_filters('caldera_forms_submit_return_redirect_required', $referrer, $form, $process_id);
2206
+
2207
+ set_transient( $process_id, $transdata, $transdata['expire']);
2208
 
2209
+ return self::form_redirect('error', $referrer, $form, $process_id );
2210
  }
2211
 
2212
 
2213
  // has processors
2214
+ do_action('caldera_forms_submit_start_processors', $form, $referrer, $process_id);
2215
  if(!empty($form['processors'])){
2216
 
2217
  // get all form processors
2218
  $form_processors = apply_filters('caldera_forms_get_form_processors', array() );
2219
+ do_action('caldera_forms_submit_pre_process_start', $form, $referrer, $process_id);
2220
+
2221
+ // PRE PROCESS
2222
  foreach($form['processors'] as $processor_id=>$processor){
2223
 
2224
  if(isset($form_processors[$processor['type']])){
2225
 
2226
  // Do Conditional
2227
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
2228
+ if(!self::check_condition($processor['conditions'], $form)){
2229
  continue;
2230
  }
2231
  }
2235
  if(!isset($process['pre_processor'])){
2236
  continue;
2237
  }
2238
+
2239
  // set default config
2240
  $config = array();
2241
+ $config['processor_id'] = $processor_id;
2242
+
2243
  if(isset($process['default'])){
2244
  $config = $process['default'];
2245
  }
2246
  if(!empty($processor['config'])){
2247
 
 
 
 
 
 
 
 
 
 
2248
  $config = array_merge($config, $processor['config']);
2249
  }
2250
  if(is_array($process['pre_processor'])){
2251
+ $process_line_data = call_user_func_array($process['pre_processor'],array($config, $form, $processid));
2252
  }else{
2253
  if(function_exists($process['pre_processor'])){
2254
  $func = $process['pre_processor'];
2255
+ $process_line_data = $func($config, $form);
2256
  }
2257
  }
2258
+ // pre processors should not return unless a break in action for further
2259
+ // Returned something - check it
2260
+ if(!empty($process_line_data)){
2261
+ if(is_array($process_line_data)){
 
2262
  //type
2263
+ if(!empty($process_line_data['type'])){
2264
+ $transdata['type'] = $process_line_data['type'];
2265
  // has note?
2266
+ if(!empty($process_line_data['note'])){
2267
+ $transdata['note'] = $process_line_data['note'];
2268
  }
2269
  }
2270
 
2271
  // fields involved?
2272
+ if(!empty($process_line_data['fields'])){
2273
+ $transdata['fields'] = $process_line_data['fields'];
2274
  }
2275
 
2276
  // set error transient
2277
+ $transdata = apply_filters('caldera_forms_submit_return_transient', $transdata, $form, $referrer, $process_id);
2278
+ $transdata = apply_filters('caldera_forms_submit_return_transient_pre_process', $transdata, $form, $referrer, $process_id);
 
 
2279
 
2280
  // back to form
2281
  $query_str = array(
2282
+ 'cf_er' => $process_id
2283
  );
2284
  if(!empty($referrer['query'])){
2285
  $query_str = array_merge($referrer['query'], $query_str);
2286
  }
2287
  $referrer = $referrer['path'] . '?' . http_build_query($query_str);
2288
+ $referrer = apply_filters('caldera_forms_submit_return_redirect', $referrer, $form, $process_id);
2289
+ $referrer = apply_filters('caldera_forms_submit_return_redirect-'.$processor['type'], $referrer, $config, $form, $process_id);
2290
+
2291
+ // set transient data
2292
+ set_transient( $process_id, $transdata, $transdata['expire']);
2293
+
2294
+ return self::form_redirect('preprocess', $referrer, $form, $process_id );
2295
  }
 
 
2296
  }
2297
  }
2298
  }
2299
+ do_action('caldera_forms_submit_pre_process_end', $form, $referrer, $process_id);
2300
  /// AFTER PRE-PROCESS - check for errors etc to return else continue to process.
2301
 
2302
+ do_action('caldera_forms_submit_process_start', $form, $referrer, $process_id);
2303
  /// PROCESS
2304
  foreach($form['processors'] as $processor_id=>$processor){
2305
  if(isset($form_processors[$processor['type']])){
2306
  // has processor
2307
  // Do Conditional
2308
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
2309
+ if(!self::check_condition($processor['conditions'], $form)){
2310
  continue;
2311
  }
2312
  }
2313
+
2314
  $process = $form_processors[$processor['type']];
2315
  if(!isset($process['processor'])){
2316
  continue;
2317
  }
2318
+ $hasmeta = null;
2319
  // set default config
2320
  $config = array();
2321
  if(isset($process['default'])){
2323
  }
2324
  if(!empty($processor['config'])){
2325
 
 
 
 
 
 
 
 
 
 
2326
  $config = array_merge($config, $processor['config']);
2327
+ }
2328
  if(is_array($process['processor'])){
2329
+ $hasmeta = call_user_func_array($process['processor'],array($config, $form));
2330
  }else{
2331
+ if(function_exists($process['processor'])){
2332
  $func = $process['processor'];
2333
+ $hasmeta = $func($config, $form);
2334
  }
2335
  }
2336
+ if($hasmeta !== null){
2337
+ foreach( (array) $hasmeta as $metakey=>$metavalue){
2338
+ $meta_process_id = $processor_id;
2339
+ // single processors are generallay used so not processor id is needed
2340
+ if(!empty($form_processors[$processor['type']]['single'])){
2341
+ $meta_process_id = $processor['type'];
2342
+ }
2343
+ self::set_submission_meta($metakey, $metavalue, $form, $processor_id);
2344
+ }
2345
+ } // check for transdata errors
2346
+
2347
+
2348
+ if(!empty($transdata['error'])){
2349
+
2350
+ // set error transient
2351
+ $transdata = apply_filters('caldera_forms_submit_error_transient', $transdata, $form, $referrer, $process_id);
2352
+ $transdata = apply_filters('caldera_forms_submit_error_transient_pre_process', $transdata, $form, $referrer, $process_id);
2353
+
2354
+ // back to form
2355
+ $query_str = array(
2356
+ 'cf_er' => $process_id
2357
+ );
2358
+ if(!empty($referrer['query'])){
2359
+ $query_str = array_merge($referrer['query'], $query_str);
2360
+ }
2361
+ $referrer = $referrer['path'] . '?' . http_build_query($query_str);
2362
+ $referrer = apply_filters('caldera_forms_submit_error_redirect', $referrer, $form, $process_id);
2363
+ $referrer = apply_filters('caldera_forms_submit_error_redirect_pre_process', $referrer, $form, $process_id);
2364
+
2365
+ // set transient data
2366
+ set_transient( $process_id, $transdata, $transdata['expire']);
2367
+
2368
+ return self::form_redirect('error', $referrer, $form, $process_id );
2369
  }
2370
+
2371
  }
2372
  }
2373
+ do_action('caldera_forms_submit_process_end', $form, $referrer, $process_id);
2374
  // AFTER PROCESS - do post process for any additional stuff
2375
+
2376
 
2377
+ do_action('caldera_forms_submit_post_process', $form, $referrer, $process_id);
2378
  // POST PROCESS
2379
  foreach($form['processors'] as $processor_id=>$processor){
2380
  if(isset($form_processors[$processor['type']])){
2381
  // has processor
2382
  // Do Conditional
2383
  if(isset($processor['conditions']) && !empty($processor['conditions']['type'])){
2384
+ if(!self::check_condition($processor['conditions'], $form)){
2385
  continue;
2386
  }
2387
  }
2397
  }
2398
  if(!empty($processor['config'])){
2399
 
 
 
 
 
 
 
 
 
 
2400
  $config = array_merge($config, $processor['config']);
2401
  }
2402
  if(is_array($process['post_processor'])){
2403
+ $hasmeta = call_user_func_array($process['post_processor'],array($config, $form));
2404
  }else{
2405
  if(function_exists($process['post_processor'])){
2406
  $func = $process['post_processor'];
2407
+ $hasmeta = $func($config, $form);
2408
  }
2409
  }
2410
+ if($hasmeta !== null){
2411
+ foreach( (array) $hasmeta as $metakey=>$metavalue){
2412
+ self::set_submission_meta($metakey, $metavalue, $form, $processor_id);
2413
+ }
 
 
2414
  }
2415
+
2416
  }
2417
  }
2418
+ do_action('caldera_forms_submit_post_process_end', $form, $referrer, $process_id);
2419
  }
2420
 
2421
  // done do action.
2422
+ do_action('caldera_forms_submit_complete', $form, $referrer, $process_id);
2423
 
2424
  // redirect back or to result page
2425
  $referrer['query']['cf_su'] = $form_instance_number;
2426
  $referrer = $referrer['path'] . '?' . http_build_query($referrer['query']);
2427
 
2428
  // filter refer
2429
+ $referrer = apply_filters('caldera_forms_submit_redirect', $referrer, $form, $process_id);
2430
+ $referrer = apply_filters('caldera_forms_submit_redirect_complete', $referrer, $form, $process_id);
2431
+
2432
+ // kill transient data
2433
+ delete_transient( $process_id );
2434
 
2435
+ return self::form_redirect('complete', $referrer, $form, $process_id );
2436
  }
2437
 
2438
  static public function check_forms_shortcode(){
2439
+ global $post, $front_templates, $wp_query, $process_id, $form;
2440
 
2441
+
2442
+ // do a form preview
2443
+
2444
+ if(!empty($_GET['cf_preview'])){
2445
+ $form = get_option($_GET['cf_preview']);
2446
+ $userid = get_current_user_id();
2447
+ if( !empty( $userid ) ){
2448
+
2449
+ if(empty($form['ID']) || $form['ID'] !== $_GET['cf_preview']){
2450
+ return;
2451
+ }
2452
+ if( empty($post) || $post->post_title !== 'Caldera Forms Preview' ){
2453
+ $temp_page = get_page_by_title('Caldera Forms Preview');
2454
+ if(empty($temp_page)){
2455
+ // create page
2456
+ $post = array(
2457
+ 'post_content' => '',
2458
+ 'post_name' => 'caldera_forms_preview',
2459
+ 'post_title' => 'Caldera Forms Preview',
2460
+ 'post_status' => 'draft',
2461
+ 'post_type' => 'page',
2462
+ 'ping_status' => 'closed',
2463
+ 'comment_status' => 'closed'
2464
+ );
2465
+ $page_id = wp_insert_post( $post );
2466
+ wp_redirect( trailingslashit( get_site_url( ) ) . '?page_id='.$page_id.'&preview=true&cf_preview='.$_GET['cf_preview'] );
2467
+ exit;
2468
+ }
2469
+ if( $temp_page->post_status !== 'draft'){
2470
+ wp_update_post( array( 'ID' => $temp_page->ID, 'post_status' => 'draft' ) );
2471
+ }
2472
+ wp_redirect( trailingslashit( get_site_url( ) ) . '?page_id='.$temp_page->ID.'&preview=true&cf_preview='.$_GET['cf_preview'] );
2473
+ exit;
2474
+ }
2475
+ $post->post_title = $form['name'];
2476
+ $post->post_content = '[caldera_form id="'.$_GET['cf_preview'].'"]';
2477
+
2478
+ }
2479
+ }
2480
+
2481
+ // catch a transient process
2482
+ if(!empty($_GET['cf_tp'])){
2483
+
2484
+ // process a transient stored entry
2485
+ $data = get_transient( $_GET['cf_tp'] );
2486
+ if(!empty($data) && $data['transient'] === $_GET['cf_tp'] && isset($data['data'])){
2487
+ // create post values
2488
+ $_POST = array_merge( $_POST, $data['data']);
2489
+ // set transient id
2490
+ $_POST['_cf_frm_tr'] = $data['transient'];
2491
+ }
2492
+ }
2493
+
2494
+
2495
+ // hook into submision
2496
  if(isset($_POST['_cf_verify']) && isset( $_POST['_cf_frm_id'] )){
2497
  if(wp_verify_nonce( $_POST['_cf_verify'], 'caldera_forms_front' )){
2498
 
2499
  self::process_submission();
2500
  exit;
2501
 
 
2502
  }
 
 
2503
  /// end form and redirect to submit page or result page.
2504
  }
2505
+
2506
+
2507
  if(empty($post)){
2508
  if(isset($wp_query->queried_object)){
2509
  $post = $wp_query->queried_object;
2516
 
2517
  // get fields
2518
 
2519
+ $field_types = self::get_field_types();
2520
 
2521
  foreach($field_types as $field_type){
2522
  //enqueue styles
2546
  // if depts been set- scripts are used -
2547
  wp_enqueue_script( 'cf-frontend-script-init', CFCORE_URL . 'assets/js/frontend-script-init.js', array('jquery'), self::VERSION, true);
2548
  $style_includes = get_option( '_caldera_forms_styleincludes' );
2549
+ $style_includes = apply_filters( 'caldera_forms_get_style_includes', $style_includes);
2550
 
2551
  if(!empty($style_includes['grid'])){
2552
  wp_enqueue_style( 'cf-grid-styles', CFCORE_URL . 'assets/css/caldera-grid.css', array(), self::VERSION );
2581
 
2582
  // has a form - get field type
2583
  if(!isset($field_types)){
2584
+ $field_types = self::get_field_types();
2585
  }
2586
 
2587
  if(!empty($form['fields'])){
2642
 
2643
  static function search_array_fields($needle, $haystack, $found = array()){
2644
 
 
2645
  if(is_array($needle)){
2646
  foreach($needle as $pin){
2647
  $found = array_merge($found, self::search_array_fields($pin, $haystack));
2664
  return;
2665
  }
2666
 
2667
+ $field_types = self::get_field_types();
2668
 
2669
  $fields = array();
2670
  foreach ($form['fields'] as $field_id => $field) {
2671
  $fields[$field['slug']] = $field;
2672
  }
2673
  }
2674
+ if(empty($form)){
2675
+ return array();
2676
+ }
2677
+
2678
  }
2679
 
2680
  global $wpdb;
2694
  return array();
2695
  }
2696
  $data = array();
2697
+ $dateformat = get_option('date_format');
2698
+ $timeformat = get_option('time_format');
2699
+ $gmt_offset = get_option( 'gmt_offset' );
2700
+
2701
  foreach($rawdata as $row){
2702
+ if(empty($form)){
2703
+ $form = get_option($row->_form_id);
2704
+ if(empty($form)){
2705
+ return array();
2706
+ }
2707
+ }
2708
 
2709
  if(isset($fields[$row->slug])){
2710
  $field = $fields[$row->slug];
2711
 
2712
  if(isset($field_types[$field['type']]['viewer'])){
2713
+ // is json?
2714
+ if(substr($row->value, 0,2) === '{"' && substr($row->value, strlen($row->value)-2 ) === '"}'){
2715
+ $is_value = json_decode($row->value, ARRAY_A);
2716
+ if(!empty($is_value)){
2717
+ $row->value = $is_value;
2718
+ }
2719
+ }
2720
 
2721
+ $row->value = apply_filters('caldera_forms_view_field_' . $field['type'], $row->value, $field, $form);
2722
+ //$row->value = apply_filters( $tag, $value );
2723
+ /*
2724
  if(is_array($field_types[$field['type']]['viewer'])){
2725
  $row->value = call_user_func_array($field_types[$field['type']]['viewer'],array($row->value, $field, $form));
2726
+ }elseif(is_object($field_types[$field['type']]['viewer'])){
2727
+
2728
+ $row->value = call_user_func_array($field_types[$field['type']]['viewer'],array($row->value, $field, $form));
2729
+
2730
+ }elseif(function_exists($field_types[$field['type']]['viewer'])){
2731
+ $func = $field_types[$field['type']]['viewer'];
2732
+ $row->value = $func($row->value, $field, $form);
2733
+ }*/
2734
  }
2735
 
2736
 
2770
  $row->value = $line;
2771
  }
2772
 
2773
+ $data['date'] = date_i18n( $dateformat.' '.$timeformat, strtotime($row->_date_submitted), $gmt_offset);
 
2774
  $data['user'] = $row->_user_id;
2775
 
2776
  $data['data'][$row->slug]['label'] = $field['label'];
2781
  }
2782
 
2783
  }else{
2784
+ // front end for editing. no filtering just values to array.
2785
  $data[$row->slug] = $row->value;
2786
  }
2787
  }
2788
+ // get meta
2789
+ $entry_detail = self::get_entry_detail($entry_id, $form);
2790
+ if(!empty($entry_detail['meta'])){
2791
+ $data['meta'] = $entry_detail['meta'];
2792
+ }
2793
+
2794
+
2795
+ if(!empty($data['user'])){
2796
+ $user = get_userdata( $data['user'] );
2797
+ if(!empty($user)){
2798
+ $data['user'] = array(
2799
+ 'ID' => $user->ID,
2800
+ 'name' => $user->data->display_name,
2801
+ 'email' => $user->data->user_email,
2802
+ 'avatar' => get_avatar( $user->ID, 150, 'identicon'),
2803
+ );
2804
+ }
2805
+ }else{
2806
+ $avatar_field = null;
2807
+ if(!empty($form['avatar_field'])){
2808
+ $avatar_field = self::get_field_data($form['avatar_field'], $form, $entry_id);
2809
+ }
2810
+ $data['user'] = array(
2811
+ 'avatar' => get_avatar( $avatar_field, 150),
2812
+ );
2813
+ }
2814
+ // allow plugins to alter the profile.
2815
+ $data['user'] = apply_filters('caldera_forms_get_entry_user', $data['user'], $entry_id, $form);
2816
+
2817
  if(!empty($_POST['form'])){
2818
  header('Content-Type: application/json');
2819
  echo json_encode( $data );
2831
  }
2832
 
2833
 
 
2834
  if(is_string($atts)){
2835
+
2836
+ $form = get_option( $atts );
2837
+
2838
+ if(empty($form['ID']) || ( empty($form['ID']) && empty($form['name']) ) ){
2839
+ $forms = get_option( '_caldera_forms' );
2840
+ //dump($forms);
2841
+ return;
2842
+ }
2843
+
2844
  $atts = array( 'id' => $atts);
2845
+ }else{
2846
+ if(empty($atts['id'])){
2847
+ if(!empty($atts['name'])){
2848
+ $forms = get_option( '_caldera_forms' );
2849
+ foreach($forms as $form_id=>$form_maybe){
2850
+ if( trim(strtolower($atts['name'])) == strtolower($form_maybe['name']) ){
2851
+ $atts['id'] = $form_id;
2852
+ break;
2853
+ }
2854
+ }
2855
+ }
2856
+
2857
+ if(empty($atts['id'])){
2858
+ return;
2859
+ }
2860
+ }
2861
+ $form = get_option( $atts['id'] );
2862
+
2863
  }
2864
 
2865
+ // set entry edit
2866
+ if(!empty($atts['entry'])){
2867
+ $entry_id = self::do_magic_tags( $atts['entry'] );
2868
  }
2869
+
2870
+ $form = apply_filters('caldera_forms_render_get_form', $form );
2871
 
 
2872
  if(empty($form)){
2873
  return;
2874
  }
2875
 
 
 
2876
  if(empty($current_form_count)){
2877
  $current_form_count = 0;
2878
  }
2879
  $current_form_count += 1;
2880
 
2881
+ $field_types = self::get_field_types();
2882
 
2883
  do_action('caldera_forms_render_start', $form);
2884
 
2909
 
2910
  $grid = new Caldera_Form_Grid($grid_settings);
2911
 
2912
+ // Build Pages Breaks
2913
+ if( false !== strpos($form['layout_grid']['structure'], '#')){
2914
+ // setup pages
2915
+ $pages = explode('#', $form['layout_grid']['structure']);
2916
+ $page_breaks = array();
2917
+ foreach($pages as $page_no=>$page){
2918
+ $point = substr_count($page, '|') + 1;
2919
+ if(isset($page_breaks[$page_no-1])){
2920
+ $point += $page_breaks[$page_no-1];
2921
+ }
2922
+ $page_breaks[$page_no] = $point;
2923
+ }
2924
+ $form['layout_grid']['structure'] = str_replace('#', '|', $form['layout_grid']['structure']);
2925
+ }
2926
 
2927
  // setup notcies
2928
  $notices = array();
2953
 
2954
  $field_errors = array();
2955
 
2956
+ // edit entry from url
2957
+ if(!empty($_GET['cf_ee'])){
2958
+ $entry_id = $_GET['cf_ee'];
2959
+ }
2960
+ // attr entry id
2961
+ if(!empty($atts['entry'])){
2962
+ $entry_id = $atts['entry'];
2963
+ }
2964
+
2965
+ if(!empty($entry_id)){
2966
+ //check user can edit this item.
2967
+ $user_id = get_current_user_id();
2968
+ if(!empty($user_id)){
2969
+
2970
+ $details = self::get_entry_detail($entry_id, $form);
2971
+
2972
+ if(!empty($details)){
2973
+ // check user can edit
2974
+ if( current_user_can( 'edit_posts' ) || $details['user_id'] === $user_id ){
2975
+ // can edit.
2976
+ $entry_id = (int) $details['id'];
2977
+ }else{
2978
+ $notices['error']['note'] = __('Permission denied or entry does not exist.', 'caldera-forms');
2979
+ }
2980
+ }else{
2981
+ $notices['error']['note'] = __('Permission denied or entry does not exist.', 'caldera-forms');
2982
+ }
2983
+
2984
+ }else{
2985
+ $notices['error']['note'] = __('Permission denied or entry does not exist.', 'caldera-forms');
2986
+ }
2987
+
2988
+ if(!empty($notices['error']['note'])){
2989
+ $halt_render = true;
2990
+ $entry_id = false;
2991
+ }
2992
+ }
2993
+
2994
  // check for prev post
2995
+ $prev_data = apply_filters('caldera_forms_render_pre_get_entry', array(), $form, $entry_id);
2996
 
2997
  // load requested data
2998
  if(!empty($entry_id)){
2999
+ $prev_data = self::get_entry($entry_id);
3000
  $prev_data = apply_filters('caldera_forms_render_get_entry', $prev_data, $form, $entry_id);
3001
  }
3002
 
3006
  if(!empty($prev_post['transient'])){
3007
 
3008
  if($prev_post['transient'] === $_GET['cf_er']){
3009
+ foreach($prev_post['data'] as $field_id=>$field_entry){
3010
+
3011
+ if(!isset($form['fields'][$field_id])){
3012
+ continue; // ignore non field data
3013
+ }
3014
+
3015
+ if(!is_wp_error( $field_entry )){
3016
+ $prev_data[$form['fields'][$field_id]['slug']] = $field_entry;
3017
+ }
3018
+ }
3019
  }
3020
  if(!empty($prev_post['type']) && !empty($prev_post['note'])){
3021
  $notices[$prev_post['type']]['note'] = $prev_post['note'];
3022
  }
3023
+ if(!empty($prev_post['error']) && !empty($prev_post['note'])){
3024
+ $notices['error']['note'] = $prev_post['note'];
3025
+ }
3026
  if(!empty($prev_post['fields'])){
3027
+ $field_errors = array();
3028
+ foreach($prev_post['fields'] as $field_id=>$field_error){
3029
+ if(is_wp_error( $field_error )){
3030
+ $field_errors[$form['fields'][$field_id]['slug']] = $field_error->get_error_message();
3031
+ }else{
3032
+ $field_errors[$form['fields'][$field_id]['slug']] = $field_error;
3033
+ }
3034
+ }
3035
  }
3036
  }
3037
  // filter transient
3044
  }
3045
  }
3046
 
3047
+ // build grid & pages
3048
+ $grid->setLayout($form['layout_grid']['structure']);
3049
+
3050
+ // insert page breaks
3051
+ if(!empty($page_breaks)){
3052
+ $currentpage = 1;
3053
+ if(isset($_GET['cf_pg']) && !isset($prev_post['page'])){
3054
+ $currentpage = (int) $_GET['cf_pg'];
3055
+ }elseif(isset($prev_post['page'])){
3056
+ $currentpage = (int) $prev_post['page'];
3057
+ }
3058
+ $display = 'none';
3059
+ if( $currentpage === 1){
3060
+ $display = 'block';
3061
+ }
3062
+
3063
+ $total_rows = substr_count($form['layout_grid']['structure'], '|') + 1;
3064
+ $grid->before('<div data-formpage="1" class="caldera-form-page" style="display:'.$display.';">', 1);
3065
+ $grid->after('</div>', $total_rows);
3066
+ //dump($page_breaks);
3067
+ foreach($page_breaks as $page=>$break){
3068
+
3069
+ $grid->after('</div>', $break);
3070
+
3071
+ if($break+1 <= $total_rows ){
3072
+ $display = 'none';
3073
+ if($page+2 == $currentpage){
3074
+ $display = 'block';
3075
+ }
3076
+
3077
+ $grid->before('<div data-formpage="' . ($page+2) . '" class="caldera-form-page" style="display:'.$display.';">', $break+1);
3078
+ }
3079
+ }
3080
+ //dump($page_breaks,0);
3081
+ //dump( $grid );
3082
+ }
3083
+
3084
+
3085
  // setup processor bound requieds
3086
  if(!empty($form['processors'])){
3087
+ $bound_fields = array();
3088
  foreach($form['processors'] as $processor_id=>$processor){
3089
+ if(!empty($processor['config']['_required_bounds'])){
3090
  foreach($processor['config'] as $slug=>&$value){
3091
+ if($slug == '_required_bounds'){
3092
+ continue;
3093
+ }
3094
+ if(in_array($slug, $processor['config']['_required_bounds'])){
3095
+ $bound_fields = array_merge($bound_fields, self::search_array_fields($value, array_keys( $form['fields'])) );
3096
+ }
3097
  }
3098
  }
3099
  }
3104
 
3105
  $conditions_templates = array();
3106
  $conditions_configs = array();
3107
+ $used_slugs = array();
3108
  if(!empty($form['layout_grid']['fields'])){
3109
 
3110
  foreach($form['layout_grid']['fields'] as $field_base_id=>$location){
3111
+ //
3112
  if(isset($form['fields'][$field_base_id])){
3113
+
3114
  $field = apply_filters('caldera_forms_render_setup_field', $form['fields'][$field_base_id], $form);
3115
 
3116
  if(empty($field) || !isset($field_types[$field['type']]['file']) || !file_exists($field_types[$field['type']]['file'])){
3117
  continue;
3118
  }
3119
+
3120
  $field_classes = array(
3121
  "control_wrapper" => "form-group",
3122
  "field_label" => "control-label",
3127
  "field_error" => "has-error",
3128
  );
3129
 
3130
+ $field_classes = apply_filters('caldera_forms_render_field_classes', $field_classes, $field, $form);
3131
+ $field_classes = apply_filters('caldera_forms_render_field_classes_type-' . $field['type'], $field_classes, $field, $form);
3132
+ $field_classes = apply_filters('caldera_forms_render_field_classes_slug-' . $field['slug'], $field_classes, $field, $form);
3133
 
3134
  $field = apply_filters('caldera_forms_render_get_field', $field, $form);
3135
  $field = apply_filters('caldera_forms_render_get_field_type-' . $field['type'], $field, $form);
3159
 
3160
  // value
3161
  if(isset($field['config']['default'])){
3162
+
3163
+ $field_structure['field_value'] = self::do_magic_tags($field['config']['default']);
3164
  }
3165
 
3166
  // transient data
3189
 
3190
  // conditional wrapper
3191
  if(!empty($field['conditions']['group']) && !empty($field['conditions']['type'])){
 
3192
 
3193
+ // render conditions check- for magic tags since at this point all field data will be null
3194
+ //if(!self::check_condition($field['conditions'], $form)){
3195
+ // dump($field['conditions'],0);
3196
+ //}
3197
+
3198
+ // wrap it up
3199
  $conditions_templates[$field_base_id] = "<script type=\"text/html\" id=\"conditional-" . $field_base_id . "-tmpl\">\r\n" . $field_html . "</script>\r\n";
3200
  $conditions_configs[$field_base_id] = $field['conditions'];
3201
  if($field['conditions']['type'] == 'show'){
3214
  //
3215
  $grid = apply_filters('caldera_forms_render_grid_structure', $grid, $form);
3216
 
3217
+ $out = "<div class=\"caldera-grid\" id=\"caldera_form_" . $current_form_count ."\">\r\n";
3218
+
3219
  $notices = apply_filters('caldera_forms_render_notices', $notices, $form);
3220
 
3221
+ $out .= '<div id="caldera_notices_'.$current_form_count.'" data-spinner="'. admin_url( 'images/spinner.gif' ).'">';
3222
  if(!empty($notices)){
3223
  // do notices
3224
  foreach($notices as $note_type => $notice){
3228
  }
3229
 
3230
  }
3231
+ $out .= '</div>';
3232
+ if((empty($notices['success']) || empty($form['hide_form'])) && empty($halt_render)){
3233
 
3234
+ $form_element = 'form';
3235
 
3236
  $form_classes = array(
3237
+ $form['ID'],
3238
+ 'caldera_forms_form',
3239
  );
3240
 
3241
  $form_attributes = array(
3244
  'role' => 'form'
3245
  );
3246
 
3247
+ $form_element = apply_filters('caldera_forms_render_form_element', $form_element, $form);
3248
  $form_classes = apply_filters('caldera_forms_render_form_classes', $form_classes, $form);
3249
  $form_attributes = apply_filters('caldera_forms_render_form_attributes', $form_attributes, $form);
3250
 
3254
  }
3255
 
3256
  // render only non success
3257
+ $out .= "<" . $form_element . " class=\"" . implode(' ', $form_classes) . "\" " . implode(" ", $attributes) . ">\r\n";
3258
  $out .= wp_nonce_field( "caldera_forms_front", "_cf_verify", true, false);
3259
  $out .= "<input type=\"hidden\" name=\"_cf_frm_id\" value=\"" . $atts['id'] . "\">\r\n";
3260
  $out .= "<input type=\"hidden\" name=\"_cf_frm_ct\" value=\"" . $current_form_count . "\">\r\n";
3261
+ // user transient for continuation
3262
+ if(!empty($prev_post['transient'])){
3263
+ $out .= "<input type=\"hidden\" name=\"_cf_frm_tr\" value=\"" . $prev_post['transient'] . "\">\r\n";
3264
+ }
3265
+ // is edit?
3266
+ if(!empty($entry_id)){
3267
+ $out .= "<input type=\"hidden\" name=\"_cf_frm_edt\" value=\"" . $entry_id . "\">\r\n";
3268
+ }
3269
+
3270
+ // auto pagination
3271
+ if(!empty($form['auto_progress']) && count($form['page_names']) > 1){
3272
+
3273
+ // retain query string
3274
+ $qurystr = array();
3275
+ parse_str( $_SERVER['QUERY_STRING'], $qurystr );
3276
+ echo "<span class=\"caldera-grid\"><ol class=\"breadcrumb\" data-form=\"caldera_form_" . $current_form_count ."\">\r\n";
3277
+ $current_page = 1;
3278
+ if(!empty($_GET['cf_pg'])){
3279
+ $current_page = $_GET['cf_pg'];
3280
+ }
3281
+ foreach($form['page_names'] as $page_key=>$page_name){
3282
+ $tabclass = null;
3283
+
3284
+ if($current_page == $page_key + 1){
3285
+ $tabclass = ' class="active"';
3286
+ }
3287
+
3288
+ $qurystr['cf_pg'] = $page_key + 1;
3289
+ $qurystr['_rdm_'] = rand(100000, 999999);
3290
+ echo "<li" . $tabclass . "><a href=\"?". http_build_query($qurystr) . "\" data-page=\"" . ( $page_key + 1 ) ."\" data-pagenav=\"caldera_form_" . $current_form_count ."\">". $page_name . "</a></li>\r\n";
3291
+ }
3292
+ echo "</ol></span>\r\n";
3293
+ }
3294
+
3295
  $out .= $grid->renderLayout();
3296
+ $out .= "</" . $form_element . ">\r\n";
3297
  }
3298
 
3299
  $out .= "</div>\r\n";
3300
 
3301
  // output javascript conditions.
3302
  if(!empty($conditions_configs) && !empty($conditions_templates)){
3303
+
3304
+ // sortout magics
3305
+ foreach($conditions_configs as &$condition_field_conf){
3306
+ if(!empty($condition_field_conf['group'])){
3307
+ foreach($condition_field_conf['group'] as &$condition_group){
3308
+ if(!empty($condition_group)){
3309
+ foreach($condition_group as &$condition_line){
3310
+ $condition_line['field'] = self::do_magic_tags( $condition_line['field'] );
3311
+ $condition_line['value'] = self::do_magic_tags( $condition_line['value'] );
3312
+ }
3313
+ }
3314
+ }
3315
+ }
3316
+ }
3317
+
3318
+ $conditions_str = json_encode($conditions_configs);
3319
+ // find %tags%
3320
+ preg_match_all("/%(.+?)%/", $conditions_str, $hastags);
3321
+ if(!empty($hastags[1])){
3322
+
3323
+ foreach($hastags[1] as $tag_key=>$tag){
3324
+
3325
+ foreach($form['fields'] as $field_id=>$field){
3326
+ if($field['slug'] === $tag){
3327
+ $conditions_str = str_replace('"'.$hastags[0][$tag_key].'"', "function(){ return jQuery('#".$field['ID']."').val(); }", $conditions_str);
3328
+ }
3329
+ }
3330
+ }
3331
+ }
3332
+
3333
+ echo "<script type=\"text/javascript\">\r\n";
3334
+ echo "var caldera_conditionals = " . $conditions_str . ";\r\n";
3335
  echo "</script>\r\n";
3336
  echo implode("\r\n", $conditions_templates);
3337
 
3338
  // enqueue conditionls app.
3339
  wp_enqueue_script( 'cf-frontend-conditionals', CFCORE_URL . 'assets/js/conditionals.js', array('jquery'), self::VERSION, true);
3340
  }
3341
+
3342
  do_action('caldera_forms_render_end', $form);
3343
 
3344
  return apply_filters('caldera_forms_render_form', $out, $form);
classes/widget.php CHANGED
@@ -9,10 +9,13 @@ class Caldera_Forms_Widget extends WP_Widget {
9
  }
10
 
11
  function widget( $args, $instance ) {
 
12
  if(!empty($instance['form'])){
13
 
14
  extract($args, EXTR_SKIP);
15
 
 
 
16
  echo $before_widget;
17
  $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);
18
  if ( !empty( $title ) ) { echo $before_title . $title . $after_title; };
@@ -35,11 +38,13 @@ class Caldera_Forms_Widget extends WP_Widget {
35
  $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
36
  $title = strip_tags($instance['title']);
37
 
38
- echo "<p><label for=\" " . $this->get_field_id('title') . "\">Title: <input class=\"widefat\" id=\"" . $this->get_field_id('title') . "\" name=\"" . $this->get_field_name('title') . "\" type=\"text\" value=\"" . attribute_escape($title). "\" /></label></p>\r\n";
 
 
39
  // get forms
40
  $forms = get_option( '_caldera_forms' );
41
 
42
- echo "<p><select style=\"width:100%;\" name=\"" . $this->get_field_name('form') . "\">\r\n";
43
 
44
  foreach($forms as $formid=>$form){
45
  $sel = "";
@@ -52,6 +57,7 @@ class Caldera_Forms_Widget extends WP_Widget {
52
  }
53
 
54
  echo "</select></p>\r\n";
 
55
  }
56
  }
57
 
9
  }
10
 
11
  function widget( $args, $instance ) {
12
+
13
  if(!empty($instance['form'])){
14
 
15
  extract($args, EXTR_SKIP);
16
 
17
+
18
+
19
  echo $before_widget;
20
  $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);
21
  if ( !empty( $title ) ) { echo $before_title . $title . $after_title; };
38
  $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
39
  $title = strip_tags($instance['title']);
40
 
41
+ do_action( 'caldera_forms_widget_form_start', $instance );
42
+
43
+ echo "<p><label for=\" " . $this->get_field_id('title') . "\">" . __('Title') . ": <input class=\"widefat\" id=\"" . $this->get_field_id('title') . "\" name=\"" . $this->get_field_name('title') . "\" type=\"text\" value=\"" . esc_attr($title). "\" /></label></p>\r\n";
44
  // get forms
45
  $forms = get_option( '_caldera_forms' );
46
 
47
+ echo "<p><label for=\" " . $this->get_field_id('title') . "\">" . __('Form') . ": </label><select style=\"width:100%;\" name=\"" . $this->get_field_name('form') . "\">\r\n";
48
 
49
  foreach($forms as $formid=>$form){
50
  $sel = "";
57
  }
58
 
59
  echo "</select></p>\r\n";
60
+ do_action( 'caldera_forms_widget_form_end', $instance, $this );
61
  }
62
  }
63
 
fields/button/config_template.html CHANGED
@@ -4,6 +4,8 @@
4
  <select class="block-input field-config" name="{{_name}}[type]">
5
  <option value="submit" {{#is type value="submit"}}selected="selected"{{/is}}>Submit</option>
6
  <option value="button" {{#is type value="button"}}selected="selected"{{/is}}>Button</option>
 
 
7
  <option value="reset" {{#is type value="reset"}}selected="selected"{{/is}}>Reset</option>
8
  </select>
9
  </div>
4
  <select class="block-input field-config" name="{{_name}}[type]">
5
  <option value="submit" {{#is type value="submit"}}selected="selected"{{/is}}>Submit</option>
6
  <option value="button" {{#is type value="button"}}selected="selected"{{/is}}>Button</option>
7
+ <option value="next" {{#is type value="next"}}selected="selected"{{/is}}>Next Page</option>
8
+ <option value="prev" {{#is type value="prev"}}selected="selected"{{/is}}>Previous Page</option>
9
  <option value="reset" {{#is type value="reset"}}selected="selected"{{/is}}>Reset</option>
10
  </select>
11
  </div>
fields/button/field.php CHANGED
@@ -1 +1,12 @@
1
- <input data-field="<?php echo $field_base_id; ?>" class="<?php echo $field['config']['class']; ?>" type="<?php echo $field['config']['type']; ?>" value="<?php echo $field['label']; ?>" id="<?php echo $field_id; ?>">
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $btnType = $field['config']['type'];
4
+ $btn_action = null;
5
+ if($field['config']['type'] == 'next' || $field['config']['type'] == 'prev'){
6
+ $btnType = 'button';
7
+ $btn_action = 'data-page="'.$field['config']['type'].'"';
8
+
9
+ }
10
+
11
+
12
+ ?><input data-field="<?php echo $field_base_id; ?>" <?php echo $btn_action; ?> class="<?php echo $field['config']['class']; ?>" type="<?php echo $btnType; ?>" value="<?php echo $field['label']; ?>" id="<?php echo $field_id; ?>">
fields/calculation/config.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="caldera-config-group">
2
+ <label for="{{_id}}_element"><?php echo __('Element', 'caldera-forms-register'); ?></label>
3
+ <div class="caldera-config-field">
4
+ <input id="{{_id}}_element" type="text" class="input-block field-config" name="{{_name}}[element]" value="{{element}}">
5
+ </div>
6
+ </div>
7
+ <div class="caldera-config-group">
8
+ <label for="{{_id}}_classes"><?php echo __('Classes', 'caldera-forms-register'); ?></label>
9
+ <div class="caldera-config-field">
10
+ <input id="{{_id}}_classes" type="text" class="input-block field-config" name="{{_name}}[classes]" value="{{classes}}">
11
+ </div>
12
+ </div>
13
+ <div class="caldera-config-group">
14
+ <label for="{{_id}}_before"><?php echo __('Before', 'caldera-forms-register'); ?></label>
15
+ <div class="caldera-config-field">
16
+ <input id="{{_id}}_before" type="text" class="input-block field-config" name="{{_name}}[before]" value="{{before}}">
17
+ </div>
18
+ </div>
19
+ <div class="caldera-config-group">
20
+ <label for="{{_id}}_after"><?php echo __('After', 'caldera-forms-register'); ?></label>
21
+ <div class="caldera-config-field">
22
+ <input id="{{_id}}_after" type="text" class="input-block field-config" name="{{_name}}[after]" value="{{after}}">
23
+ </div>
24
+ </div>
25
+ <div class="caldera-config-group">
26
+ <div class="caldera-config-field">
27
+ <label><input id="{{_id}}_fixed" type="checkbox" class="field-config" name="{{_name}}[fixed]" value="1" {{#if fixed}}checked="checked"{{/if}}> <?php echo __('Money Format', 'caldera-forms-calculator'); ?></label>
28
+ </div>
29
+ </div>
30
+ <div class="caldera-config-group">
31
+ <div class="caldera-config-field">
32
+ <label><input id="{{_id}}_manual" type="checkbox" class="field-config" name="{{_name}}[manual]" value="1" {{#if manual}}checked="checked"{{/if}}> <?php echo __('Manual Formula', 'caldera-forms-calculator'); ?></label>
33
+ </div>
34
+ </div>
35
+ <div id="{{_id}}_autobox">
36
+ <div class="caldera-config-group caldera-config-group-full">
37
+ <button type="button" class="button block-button add-operator-group ajax-trigger"
38
+ data-template="#calculator-group-tmpl"
39
+ data-target="#{{_id}}_operator_groups"
40
+ data-target-insert="append"
41
+ data-name="{{_name}}"
42
+ data-id="{{_id}}"
43
+ data-request="calc_add_group"
44
+ data-callback="init_calc_group"
45
+ ><?php echo __('Add Operator Group'); ?></button>
46
+ </div>
47
+ <br>
48
+ <div id="{{_id}}_operator_groups" class="calculation-groups-wrap"></div>
49
+ <input type="hidden" class="block-input field-config calculation-formular" name="{{_name}}[formular]" id="{{_id}}_formular" value="{{formular}}">
50
+ <input type="hidden" class="block-input field-config ajax-trigger" data-request="build_calc_structure" data-callback="{{_id}}_build_formula" data-init="{{_id}}_build_formula" data-event="none" data-autoload="true" data-template="#calculator-group-tmpl" data-target="#{{_id}}_operator_groups" name="{{_name}}[config]" id="{{_id}}_config" value="{{config}}">
51
+ </div>
52
+ <div id="{{_id}}_manualbox" style="display:none;">
53
+ <textarea name="{{_name}}[manual_formula]" class="field-config block-input">{{manual_formula}}</textarea>
54
+ <p class="description"><?php echo __('Use %field_slug% as field vaule variables', 'caldera-forms'); ?></p>
55
+ </div>
56
+ <br><br><br>
57
+ {{#script}}
58
+ //<script>
59
+
60
+
61
+ function {{_id}}_build_formula(obj){
62
+
63
+ build_calculations_formular('{{_id}}', obj);
64
+
65
+ };
66
+
67
+ jQuery('#{{_id}}_operator_groups').on('change', 'select', function(e){
68
+ {{_id}}_build_formula();
69
+ });
70
+ jQuery('body').on('change', '#{{_id}}_manual', function(e){
71
+ var checked = jQuery(this);
72
+
73
+ if(checked.prop('checked')){
74
+ jQuery('#{{_id}}_autobox').hide();
75
+ jQuery('#{{_id}}_manualbox').show();
76
+ }else{
77
+ jQuery('#{{_id}}_autobox').show();
78
+ jQuery('#{{_id}}_manualbox').hide();
79
+ }
80
+ });
81
+
82
+ jQuery('#{{_id}}_manual').trigger('change');
83
+
84
+ {{/script}}
85
+
86
+
87
+
88
+
89
+
90
+
91
+
fields/calculation/field.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $elementType = $field['config']['element'];
4
+ if(empty($elementType)){
5
+ $elementType = 'div';
6
+ }
7
+
8
+ if(!empty($field['config']['before'])){
9
+ $field['config']['before'] = self::do_magic_tags($field['config']['before']);
10
+ }
11
+ if(!empty($field['config']['after'])){
12
+ $field['config']['after'] = self::do_magic_tags($field['config']['after']);
13
+ }
14
+
15
+ ?><div class="<?php echo $field_wrapper_class; ?>">
16
+ <?php echo $field_label; ?>
17
+ <div class="<?php echo $field_input_class; ?>">
18
+ <<?php echo $elementType; ?> class="<?php echo $field['config']['classes']; ?>"><?php echo $field['config']['before']; ?><span id="<?php echo $field_id; ?>"><?php echo $field_value; ?></span><?php echo $field['config']['after']; ?></<?php echo $elementType; ?>>
19
+ <input type="hidden" name="<?php echo $field_name; ?>" value="0" data-field="<?php echo $field_base_id; ?>" >
20
+ <?php echo $field_caption; ?>
21
+ </div>
22
+ </div>
23
+ <?php
24
+ $formula = $field['config']['formular'];
25
+
26
+ if(!empty($field['config']['manual'])){
27
+ $formula = $field['config']['manual_formula'];
28
+ preg_match_all("/%(.+?)%/", $formula, $hastags);
29
+ if(!empty($hastags[1])){
30
+ $binds = array();
31
+
32
+ foreach($hastags[1] as $tag_key=>$tag){
33
+
34
+ foreach($form['fields'] as $key_id=>$fcfg){
35
+ if($fcfg['slug'] === $tag){
36
+ $binds[] = '#'.$key_id;
37
+ $bindfields[] = '"'.$key_id.'"';
38
+ $formula = str_replace($hastags[0][$tag_key], $key_id, $formula);
39
+ }
40
+ }
41
+ }
42
+ }
43
+ // fix POW
44
+ $formula = str_replace('pow(', 'Math.pow(', $formula);
45
+
46
+ }
47
+ $formula = str_replace("\r",'', str_replace("\n",'', str_replace(' ','', trim( self::do_magic_tags( $formula ) ) ) ) );
48
+
49
+ $binds = array();
50
+ $binds_wrap = array();
51
+ $binds_vars = array();
52
+ foreach($form['fields'] as $fid=>$cfg){
53
+ if(false !== strpos($formula, $fid)){
54
+ $binds_vars[] = $fid." = parseFloat( $('[data-field=\"".$fid."\"]').is(':checkbox') ? checked_total_" . $field_base_id. "($('[data-field=\"".$fid."\"]:checked')) : $('[data-field=\"".$fid."\"]').is(':radio') ? $('[data-field=\"".$fid."\"]:checked').val() : $('[data-field=\"".$fid."\"]').val() ) || 0 ";
55
+ $binds[] = "[data-field=\"".$fid."\"]";
56
+ // include a conditional wrapper
57
+ $binds_wrap[] = "#conditional_".$fid;
58
+ }
59
+ }
60
+
61
+
62
+ if(!empty($binds)){
63
+ $bindtriggers = array_merge($binds, $binds_wrap);
64
+
65
+ ?>
66
+ <script type="text/javascript">
67
+ jQuery(function($){
68
+ function checked_total_<?php echo $field_base_id; ?>(items){
69
+ var sum = 0;
70
+ items.each(function(k,v){
71
+ sum += parseFloat($(v).val());
72
+ })
73
+ return sum;
74
+ }
75
+ function docalc_<?php echo $field_base_id; ?>(){
76
+ var <?php echo implode(', ',$binds_vars); ?>,
77
+ total = <?php echo $formula; ?>;
78
+
79
+
80
+ <?php if(!empty($field['config']['fixed'])){ ?>
81
+ total = total.toFixed(2);
82
+ <?php } ?>
83
+
84
+ $('#<?php echo $field_id; ?>').html( total );
85
+ $('[data-field="<?php echo $field_base_id; ?>"]').val( total ).trigger('change');
86
+
87
+ }
88
+ $('body').on('change keyup cf.remove cf.add', '<?php echo implode(',', $bindtriggers); ?>', function(e){
89
+ docalc_<?php echo $field_base_id; ?>();
90
+ });
91
+ docalc_<?php echo $field_base_id; ?>();
92
+ });
93
+
94
+ </script>
95
+ <?php } ?>
fields/calculation/line-templates.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="calculator-group-tmpl">
2
+ {{#each group}}
3
+
4
+ {{#if operator}}
5
+
6
+ <div class="caldera-config-group caldera-config-group-full calculation-group-connect calculation-group" style="text-align:center;">
7
+ <select class="calculation-operator">
8
+ <option value="+" {{#is operator value="+"}}selected="selected"{{/is}}>+</option>
9
+ <option value="-" {{#is operator value="-"}}selected="selected"{{/is}}>&minus;</option>
10
+ <option value="*" {{#is operator value="*"}}selected="selected"{{/is}}>&times;</option>
11
+ <option value="/" {{#is operator value="/"}}selected="selected"{{/is}}>&divide;</option>
12
+ </select>
13
+ </div>
14
+
15
+ {{else}}
16
+
17
+ <div class="caldera-config-group caldera-config-group-full calculation-group">
18
+ <div class="calculation-group-lines">
19
+ {{#each lines}}
20
+ <div class="calculation-group-line">
21
+ <select class="calculation-operator">
22
+ <option value="+" {{#is operator value="+"}}selected="selected"{{/is}}>+</option>
23
+ <option value="-" {{#is operator value="-"}}selected="selected"{{/is}}>&minus;</option>
24
+ <option value="*" {{#is operator value="*"}}selected="selected"{{/is}}>&times;</option>
25
+ <option value="/" {{#is operator value="/"}}selected="selected"{{/is}}>&divide;</option>
26
+ </select>
27
+ <select class="calculation-operator-field caldera-field-bind" data-default="{{field}}" style="max-width:229px;width:229px;"></select>
28
+ <button class="button remove-operator-line pull-right" type="button"><i class="icon-join"></i></button>
29
+ </div>
30
+ {{/each}}
31
+ </div>
32
+ <button type="button" class="button button-small calculation-add-line" style="margin-top: 12px;">Add Line</button>
33
+ </div>
34
+
35
+ {{/if}}
36
+
37
+ {{/each}}
38
+ </script>
39
+ <script type="text/javascript">
40
+
41
+ function build_calc_structure(obj){
42
+ var config = {};
43
+ if(obj.trigger.val().length){
44
+ config = JSON.parse(obj.trigger.val());
45
+ config.init = obj.trigger.data('init');
46
+ }
47
+ return config;
48
+ }
49
+ function init_calc_group(obj){
50
+ obj.params.target.find('select').first().trigger('change');
51
+ rebuild_field_binding();
52
+ }
53
+ function calc_add_group(obj){
54
+ var groups = {
55
+ lines : [
56
+ {
57
+ operator : '+',
58
+ field : ''
59
+ }
60
+ ]
61
+ },
62
+ out = {group : []};
63
+
64
+ if(obj.target.find('.calculation-group').length){
65
+ out.group.push({
66
+ operator : '+'
67
+ });
68
+ }
69
+
70
+ out.group.push(groups);
71
+
72
+ return out;
73
+ }
74
+ function build_calculations_formular(id, obj){
75
+ var wrap = jQuery('#'+id+'_operator_groups'),
76
+ groups = wrap.find('.calculation-group'),
77
+ formula = '',
78
+ formular_input = jQuery('#' + id + '_formular'),
79
+ config_input = jQuery('#' + id + '_config'),
80
+ config = {
81
+ group: []
82
+ };
83
+
84
+ groups.each(function(k,v){
85
+ //console.log(v);
86
+ var lines = jQuery(v).find('.calculation-group-line'),
87
+ connector = jQuery(v).find('.calculation-operator'),
88
+ group = {};
89
+
90
+ if(lines.length){
91
+
92
+ group.lines = [];
93
+ // lines
94
+ jQuery(v).find('.calculation-operator').first().prop('disabled', true).hide();
95
+ jQuery(v).find('.calculation-operator-field').first().css({'maxWidth': '272px', 'width': '272px'});
96
+
97
+ if(lines.length > 1){
98
+ formula += ' ( ';
99
+ }
100
+ lines.each(function(l,b){
101
+
102
+ var op = jQuery(b).find('.calculation-operator'),
103
+ fi = jQuery(b).find('.calculation-operator-field'),
104
+ line = {
105
+ operator : '+',
106
+ field : ''
107
+ };
108
+
109
+ if(fi.val()){
110
+ if(op.length){
111
+ if(op.prop('disabled') !== true){
112
+ formula += op.val();
113
+ line.operator = op.val();
114
+ }
115
+ }
116
+ if(op.length){
117
+ formula += fi.val();
118
+ line.field = fi.val();
119
+ }
120
+ }
121
+ group.lines.push(line);
122
+ });
123
+
124
+ if(lines.length > 1){
125
+ formula += ' ) ';
126
+ }
127
+ }else if(connector.length){
128
+ // connector
129
+ formula += connector.val();
130
+ group.operator = connector.val();
131
+ }
132
+
133
+ config.group.push(group);
134
+ });
135
+ if(typeof obj === 'undefined'){
136
+ formular_input.val(formula);
137
+ config_input.val(JSON.stringify(config));
138
+ }
139
+ }
140
+ jQuery(function($){
141
+ $('body').on('click', '.calculation-add-line', function(e){
142
+
143
+ var clicked = $(this),
144
+ lastline = clicked.prev().find('.calculation-group-line').last().clone();
145
+
146
+ lastline.find('select').css({'width': "", 'maxWidth' : ""}).prop('disabled',false).show();
147
+ lastline.appendTo(clicked.prev());
148
+ lastline.find('select').first().trigger('change');
149
+
150
+ });
151
+ $('body').on('click', '.remove-operator-line', function(e){
152
+
153
+ var clicked = $(this),
154
+ row = clicked.parent(),
155
+ group = clicked.closest('.caldera-config-group'),
156
+ wrap = clicked.closest('.calculation-groups-wrap');
157
+
158
+ row.remove();
159
+ if(!group.find('.calculation-group-line').length){
160
+ if(group.prev().hasClass('calculation-group-connect')){
161
+ group.prev().remove();
162
+ }
163
+ group.remove();
164
+
165
+ }
166
+ //calculation-formular
167
+ var trigger = wrap.find('select:first');
168
+ if(trigger.length){
169
+ wrap.find('select:first').trigger('change');
170
+ }else{
171
+ wrap.next().val('');
172
+ }
173
+ });
174
+ })
175
+
176
+ </script>
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+
196
+
197
+
fields/calculation/preview.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <div class="preview-caldera-config-group">
2
+ {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
+ <div class="preview-caldera-config-field">
4
+ <{{config/element}} class="{{config/classes}}">{{config/before}}0{{#if config/fixed}}.00{{/if}}{{config/after}}</{{config/element}}>
5
+ <span class="help-block">{{caption}}</span>
6
+ </div>
7
+ </div>
fields/calculation/style.css ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ .calculation-group {
2
+ background: none repeat scroll 0 0 #FFFFFF;
3
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
4
+ padding: 6px;
5
+ margin: 6px 0;
6
+ }
fields/checkbox/field.php CHANGED
@@ -7,12 +7,16 @@
7
  <input type="checkbox" id="<?php echo $field_id; ?>" data-field="<?php echo $field_base_id; ?>" class="field-config" name="<?php echo $field_name; ?>" value="1" <?php if(!empty($field_value)){ ?>checked="true"<?php } ?>>
8
 
9
  <?php }else{
 
10
  foreach($field['config']['option'] as $option_key=>$option){
 
 
 
11
  ?>
12
  <?php if(empty($field['config']['inline'])){ ?>
13
  <div class="checkbox">
14
  <?php } ?>
15
- <label<?php if(!empty($field['config']['inline'])){ ?> class="checkbox-inline"<?php } ?>><input type="checkbox" data-field="<?php echo $field_base_id; ?>" id="<?php echo $field_id . '_' . $option_key; ?>" class="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>[]" value="<?php echo $option['value']; ?>" <?php if( in_array( $option['value'], (array) $field_value) ){ ?>checked="true"<?php } ?>> <?php echo $option['label']; ?></label>&nbsp;
16
  <?php if(empty($field['config']['inline'])){ ?>
17
  </div>
18
  <?php } ?>
7
  <input type="checkbox" id="<?php echo $field_id; ?>" data-field="<?php echo $field_base_id; ?>" class="field-config" name="<?php echo $field_name; ?>" value="1" <?php if(!empty($field_value)){ ?>checked="true"<?php } ?>>
8
 
9
  <?php }else{
10
+
11
  foreach($field['config']['option'] as $option_key=>$option){
12
+ if(!isset($option['value'])){
13
+ $option['value'] = htmlspecialchars( $option['label'] );
14
+ }
15
  ?>
16
  <?php if(empty($field['config']['inline'])){ ?>
17
  <div class="checkbox">
18
  <?php } ?>
19
+ <label<?php if(!empty($field['config']['inline'])){ ?> class="checkbox-inline"<?php } ?>><input type="checkbox" data-field="<?php echo $field_base_id; ?>" id="<?php echo $field_id . '_' . $option_key; ?>" class="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>[<?php echo $option_key; ?>]" value="<?php echo $option['value']; ?>" <?php if( in_array( $option['value'], (array) $field_value) ){ ?>checked="true"<?php } ?>> <?php echo $option['label']; ?></label>&nbsp;
20
  <?php if(empty($field['config']['inline'])){ ?>
21
  </div>
22
  <?php } ?>
fields/checkbox/preview.php CHANGED
@@ -6,7 +6,7 @@
6
  {{#unless ../config/inline}}
7
  <div>
8
  {{/unless}}
9
- <label style="margin: 0px 10px 0px 0px;"><input type="checkbox" class="preview-field-config" {{#is default value=true}}checked="checked"{{/is}}> {{label}}</label>
10
  {{#unless ../config/inline}}
11
  </div>
12
  {{/unless}}
6
  {{#unless ../config/inline}}
7
  <div>
8
  {{/unless}}
9
+ <label style="margin: 0px 10px 0px 0px;"><input type="checkbox" class="preview-field-config" {{#is ../config/default value="@key"}}checked="checked"{{/is}}> {{label}}</label>
10
  {{#unless ../config/inline}}
11
  </div>
12
  {{/unless}}
fields/color_picker/field.php CHANGED
@@ -1,7 +1,7 @@
1
  <div class="<?php echo $field_wrapper_class; ?> cf-color-picker">
2
  <?php echo $field_label; ?>
3
  <div class="picker-row">
4
- <div class="<?php echo $field_input_class; ?> col-sm-5 col-md-4 input-group">
5
  <input <?php echo $field_placeholder; ?> id="<?php echo $field_id; ?>" data-field="<?php echo $field_base_id; ?>" type="text" class="<?php echo $field_class; ?> minicolor-picker init_field_type" data-type="color_picker" name="<?php echo $field_name; ?>" value="<?php echo $field_value; ?>" <?php echo $field_required; ?>>
6
  </div>
7
  </div>
1
  <div class="<?php echo $field_wrapper_class; ?> cf-color-picker">
2
  <?php echo $field_label; ?>
3
  <div class="picker-row">
4
+ <div class="<?php echo $field_input_class; ?> input-group">
5
  <input <?php echo $field_placeholder; ?> id="<?php echo $field_id; ?>" data-field="<?php echo $field_base_id; ?>" type="text" class="<?php echo $field_class; ?> minicolor-picker init_field_type" data-type="color_picker" name="<?php echo $field_name; ?>" value="<?php echo $field_value; ?>" <?php echo $field_required; ?>>
6
  </div>
7
  </div>
fields/color_picker/minicolors.js CHANGED
@@ -6,7 +6,7 @@
6
  * Dual licensed under the MIT or GPL Version 2 licenses
7
  *
8
  */
9
- if(jQuery)(function($){$.extend($.fn,{miniColors:function(o,data){var create=function(input,o,data){var color=expandHex(input.val());if(!color)color='ffffff';var hsb=hex2hsb(color);var trigger=$('<span class="input-group-addon" style="background-color: #'+color+'" href="#"></span>');trigger.insertAfter(input);input.addClass('miniColors').data('original-maxlength',input.attr('maxlength')||null).data('original-autocomplete',input.attr('autocomplete')||null).data('letterCase',o.letterCase?o.letterCase:'uppercase').data('trigger',trigger).data('hsb',hsb).data('change',o.change?o.change:null).data('close',o.close?o.close:null).data('open',o.open?o.open:null).attr('maxlength',7).attr('autocomplete','off').val('#'+convertCase(color,o.letterCase)).trigger('change');if(o.readonly)input.prop('readonly',true);if(o.disabled)disable(input);trigger.on('click.miniColors',function(event){event.preventDefault();if(input.val()==='')input.val('#').trigger('change');show(input)});input.on('focus.miniColors',function(event){if(input.val()==='')input.val('#').trigger('change');show(input)});input.on('blur.miniColors',function(event){var hex=expandHex(hsb2hex(input.data('hsb')));input.val(hex?'#'+convertCase(hex,input.data('letterCase')):'').trigger('change')});input.on('keydown.miniColors',function(event){if(event.keyCode===9)hide(input)});input.on('keyup.miniColors',function(event){setColorFromInput(input)});input.on('paste.miniColors',function(event){setTimeout(function(){setColorFromInput(input)},5)})};var destroy=function(input){hide();input=$(input);input.data('trigger').remove();input.attr('autocomplete',input.data('original-autocomplete')).attr('maxlength',input.data('original-maxlength')).removeData().removeClass('miniColors').off('.miniColors');$(document).off('.miniColors')};var enable=function(input){input.prop('disabled',false).data('trigger').css('opacity',1)};var disable=function(input){hide(input);input.prop('disabled',true).data('trigger').css('opacity',0.5)};var show=function(input){if(input.prop('disabled'))return false;hide();var selector=$('<div class="miniColors-selector"></div>');selector.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"><div class="miniColors-colorPicker-inner"></div></div>').append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>').css('display','none').addClass(input.attr('class'));var hsb=input.data('hsb');selector.find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));var colorPosition=input.data('colorPosition');if(!colorPosition)colorPosition=getColorPositionFromHSB(hsb);selector.find('.miniColors-colorPicker').css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');var huePosition=input.data('huePosition');if(!huePosition)huePosition=getHuePositionFromHSB(hsb);selector.find('.miniColors-huePicker').css('top',huePosition.y+'px');input.data('selector',selector).data('huePicker',selector.find('.miniColors-huePicker')).data('colorPicker',selector.find('.miniColors-colorPicker')).data('mousebutton',0);$('BODY').append(selector);var trigger=input.data('trigger'),hidden=!input.is(':visible'),top=hidden?trigger.offset().top+trigger.outerHeight():input.offset().top+input.outerHeight(),left=hidden?trigger.offset().left:input.offset().left,selectorWidth=selector.outerWidth(),selectorHeight=selector.outerHeight(),triggerWidth=trigger.outerWidth(),triggerHeight=trigger.outerHeight(),windowHeight=$(window).height(),windowWidth=$(window).width(),scrollTop=$(window).scrollTop(),scrollLeft=$(window).scrollLeft();if((top+selectorHeight)>windowHeight+scrollTop)top=top-selectorHeight-triggerHeight;if((left+selectorWidth)>windowWidth+scrollLeft)left=left-selectorWidth+triggerWidth;selector.css({top:top,left:left}).fadeIn(100);selector.on('selectstart',function(){return false});if(!$.browser.msie||($.browser.msie&&$.browser.version>=9)){$(window).on('resize.miniColors',function(event){hide(input)})}$(document).on('mousedown.miniColors touchstart.miniColors',function(event){input.data('mousebutton',1);var testSubject=$(event.target).parents().andSelf();if(testSubject.hasClass('miniColors-colors')){event.preventDefault();input.data('moving','colors');moveColor(input,event)}if(testSubject.hasClass('miniColors-hues')){event.preventDefault();input.data('moving','hues');moveHue(input,event)}if(testSubject.hasClass('miniColors-selector')){event.preventDefault();return}if(testSubject.hasClass('miniColors'))return;hide(input)});$(document).on('mouseup.miniColors touchend.miniColors',function(event){event.preventDefault();input.data('mousebutton',0).removeData('moving')}).on('mousemove.miniColors touchmove.miniColors',function(event){event.preventDefault();if(input.data('mousebutton')===1){if(input.data('moving')==='colors')moveColor(input,event);if(input.data('moving')==='hues')moveHue(input,event)}});if(input.data('open')){input.data('open').call(input.get(0),'#'+hsb2hex(hsb),hsb2rgb(hsb))}};var hide=function(input){if(!input)input=$('.miniColors');input.each(function(){var selector=$(this).data('selector');$(this).removeData('selector');$(selector).fadeOut(100,function(){if(input.data('close')){var hsb=input.data('hsb'),hex=hsb2hex(hsb);input.data('close').call(input.get(0),'#'+hex,hsb2rgb(hsb))}$(this).remove()})});$(document).off('.miniColors')};var moveColor=function(input,event){var colorPicker=input.data('colorPicker');colorPicker.hide();var position={x:event.pageX,y:event.pageY};if(event.originalEvent.changedTouches){position.x=event.originalEvent.changedTouches[0].pageX;position.y=event.originalEvent.changedTouches[0].pageY}position.x=position.x-input.data('selector').find('.miniColors-colors').offset().left-5;position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-5;if(position.x<=-5)position.x=-5;if(position.x>=144)position.x=144;if(position.y<=-5)position.y=-5;if(position.y>=144)position.y=144;input.data('colorPosition',position);colorPicker.css('left',position.x).css('top',position.y).show();var s=Math.round((position.x+5)*0.67);if(s<0)s=0;if(s>100)s=100;var b=100-Math.round((position.y+5)*0.67);if(b<0)b=0;if(b>100)b=100;var hsb=input.data('hsb');hsb.s=s;hsb.b=b;setColor(input,hsb,true)};var moveHue=function(input,event){var huePicker=input.data('huePicker');huePicker.hide();var position={y:event.pageY};if(event.originalEvent.changedTouches){position.y=event.originalEvent.changedTouches[0].pageY}position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-1;if(position.y<=-1)position.y=-1;if(position.y>=149)position.y=149;input.data('huePosition',position);huePicker.css('top',position.y).show();var h=Math.round((150-position.y-1)*2.4);if(h<0)h=0;if(h>360)h=360;var hsb=input.data('hsb');hsb.h=h;setColor(input,hsb,true)};var setColor=function(input,hsb,updateInput){input.data('hsb',hsb);var hex=hsb2hex(hsb);if(updateInput)input.val('#'+convertCase(hex,input.data('letterCase'))).trigger('change');input.data('trigger').css('backgroundColor','#'+hex);if(input.data('selector'))input.data('selector').find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));if(input.data('change')){if(hex===input.data('lastChange'))return;input.data('change').call(input.get(0),'#'+hex,hsb2rgb(hsb));input.data('lastChange',hex)}};var setColorFromInput=function(input){input.val('#'+cleanHex(input.val())).trigger('change');var hex=expandHex(input.val());if(!hex)return false;var hsb=hex2hsb(hex);var currentHSB=input.data('hsb');if(hsb.h===currentHSB.h&&hsb.s===currentHSB.s&&hsb.b===currentHSB.b)return true;var colorPosition=getColorPositionFromHSB(hsb);var colorPicker=$(input.data('colorPicker'));colorPicker.css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');input.data('colorPosition',colorPosition);var huePosition=getHuePositionFromHSB(hsb);var huePicker=$(input.data('huePicker'));huePicker.css('top',huePosition.y+'px');input.data('huePosition',huePosition);setColor(input,hsb);return true};var convertCase=function(string,letterCase){if(letterCase==='lowercase')return string.toLowerCase();if(letterCase==='uppercase')return string.toUpperCase();return string};var getColorPositionFromHSB=function(hsb){var x=Math.ceil(hsb.s/0.67);if(x<0)x=0;if(x>150)x=150;var y=150-Math.ceil(hsb.b/0.67);if(y<0)y=0;if(y>150)y=150;return{x:x-5,y:y-5}};var getHuePositionFromHSB=function(hsb){var y=150-(hsb.h/2.4);if(y<0)h=0;if(y>150)h=150;return{y:y-1}};var cleanHex=function(hex){return hex.replace(/[^A-F0-9]/ig,'')};var expandHex=function(hex){hex=cleanHex(hex);if(!hex)return null;if(hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];return hex.length===6?hex:null};var hsb2rgb=function(hsb){var rgb={};var h=Math.round(hsb.h);var s=Math.round(hsb.s*255/100);var v=Math.round(hsb.b*255/100);if(s===0){rgb.r=rgb.g=rgb.b=v}else{var t1=v;var t2=(255-s)*v/255;var t3=(t1-t2)*(h%60)/60;if(h===360)h=0;if(h<60){rgb.r=t1;rgb.b=t2;rgb.g=t2+t3}else if(h<120){rgb.g=t1;rgb.b=t2;rgb.r=t1-t3}else if(h<180){rgb.g=t1;rgb.r=t2;rgb.b=t2+t3}else if(h<240){rgb.b=t1;rgb.r=t2;rgb.g=t1-t3}else if(h<300){rgb.b=t1;rgb.g=t2;rgb.r=t2+t3}else if(h<360){rgb.r=t1;rgb.g=t2;rgb.b=t1-t3}else{rgb.r=0;rgb.g=0;rgb.b=0}}return{r:Math.round(rgb.r),g:Math.round(rgb.g),b:Math.round(rgb.b)}};var rgb2hex=function(rgb){var hex=[rgb.r.toString(16),rgb.g.toString(16),rgb.b.toString(16)];$.each(hex,function(nr,val){if(val.length===1)hex[nr]='0'+val});return hex.join('')};var hex2rgb=function(hex){hex=parseInt(((hex.indexOf('#')>-1)?hex.substring(1):hex),16);return{r:hex>>16,g:(hex&0x00FF00)>>8,b:(hex&0x0000FF)}};var rgb2hsb=function(rgb){var hsb={h:0,s:0,b:0};var min=Math.min(rgb.r,rgb.g,rgb.b);var max=Math.max(rgb.r,rgb.g,rgb.b);var delta=max-min;hsb.b=max;hsb.s=max!==0?255*delta/max:0;if(hsb.s!==0){if(rgb.r===max){hsb.h=(rgb.g-rgb.b)/delta}else if(rgb.g===max){hsb.h=2+(rgb.b-rgb.r)/delta}else{hsb.h=4+(rgb.r-rgb.g)/delta}}else{hsb.h=-1}hsb.h*=60;if(hsb.h<0){hsb.h+=360}hsb.s*=100/255;hsb.b*=100/255;return hsb};var hex2hsb=function(hex){var hsb=rgb2hsb(hex2rgb(hex));if(hsb.s===0)hsb.h=360;return hsb};var hsb2hex=function(hsb){return rgb2hex(hsb2rgb(hsb))};switch(o){case'readonly':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).prop('readonly',data)});return $(this);case'disabled':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;if(data){disable($(this))}else{enable($(this))}});return $(this);case'value':if(data===undefined){if(!$(this).hasClass('miniColors'))return;var input=$(this),hex=expandHex(input.val());return hex?'#'+convertCase(hex,input.data('letterCase')):null}$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).val(data).trigger('change');setColorFromInput($(this))});return $(this);case'destroy':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;destroy($(this))});return $(this);default:if(!o)o={};$(this).each(function(){if($(this)[0].tagName.toLowerCase()!=='input')return;if($(this).data('trigger'))return;create($(this),o,data)});return $(this)}}})})(jQuery);
10
  function color_picker_init(){
11
  jQuery('.minicolor-picker').miniColors();
12
  }
6
  * Dual licensed under the MIT or GPL Version 2 licenses
7
  *
8
  */
9
+ if(jQuery)(function($){$.extend($.fn,{miniColors:function(o,data){var create=function(input,o,data){var color=expandHex(input.val());if(!color)color='ffffff';var hsb=hex2hsb(color);var trigger=$('<span class="input-group-addon" style="background-color: #'+color+'" href="#"></span>');trigger.insertAfter(input);input.addClass('miniColors').data('original-maxlength',input.attr('maxlength')||null).data('original-autocomplete',input.attr('autocomplete')||null).data('letterCase',o.letterCase?o.letterCase:'uppercase').data('trigger',trigger).data('hsb',hsb).data('change',o.change?o.change:null).data('close',o.close?o.close:null).data('open',o.open?o.open:null).attr('maxlength',7).attr('autocomplete','off').val('#'+convertCase(color,o.letterCase)).trigger('change');if(o.readonly)input.prop('readonly',true);if(o.disabled)disable(input);trigger.on('click.miniColors',function(event){event.preventDefault();if(input.val()==='')input.val('#').trigger('change');show(input)});input.on('focus.miniColors',function(event){if(input.val()==='')input.val('#').trigger('change');show(input)});input.on('blur.miniColors',function(event){var hex=expandHex(hsb2hex(input.data('hsb')));input.val(hex?'#'+convertCase(hex,input.data('letterCase')):'').trigger('change')});input.on('keydown.miniColors',function(event){if(event.keyCode===9)hide(input)});input.on('keyup.miniColors',function(event){setColorFromInput(input)});input.on('paste.miniColors',function(event){setTimeout(function(){setColorFromInput(input)},5)})};var destroy=function(input){hide();input=$(input);input.data('trigger').remove();input.attr('autocomplete',input.data('original-autocomplete')).attr('maxlength',input.data('original-maxlength')).removeData().removeClass('miniColors').off('.miniColors');$(document).off('.miniColors')};var enable=function(input){input.prop('disabled',false).data('trigger').css('opacity',1)};var disable=function(input){hide(input);input.prop('disabled',true).data('trigger').css('opacity',0.5)};var show=function(input){if(input.prop('disabled'))return false;hide();var selector=$('<div class="miniColors-selector"></div>');selector.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"><div class="miniColors-colorPicker-inner"></div></div>').append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>').css('display','none').addClass(input.attr('class')).removeClass('form-control');var hsb=input.data('hsb');selector.find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));var colorPosition=input.data('colorPosition');if(!colorPosition)colorPosition=getColorPositionFromHSB(hsb);selector.find('.miniColors-colorPicker').css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');var huePosition=input.data('huePosition');if(!huePosition)huePosition=getHuePositionFromHSB(hsb);selector.find('.miniColors-huePicker').css('top',huePosition.y+'px');input.data('selector',selector).data('huePicker',selector.find('.miniColors-huePicker')).data('colorPicker',selector.find('.miniColors-colorPicker')).data('mousebutton',0);$('BODY').append(selector);var trigger=input.data('trigger'),hidden=!input.is(':visible'),top=hidden?trigger.offset().top+trigger.outerHeight():input.offset().top+input.outerHeight(),left=hidden?trigger.offset().left:input.offset().left,selectorWidth=selector.outerWidth(),selectorHeight=selector.outerHeight(),triggerWidth=trigger.outerWidth(),triggerHeight=trigger.outerHeight(),windowHeight=$(window).height(),windowWidth=$(window).width(),scrollTop=$(window).scrollTop(),scrollLeft=$(window).scrollLeft();if((top+selectorHeight)>windowHeight+scrollTop)top=top-selectorHeight-triggerHeight;if((left+selectorWidth)>windowWidth+scrollLeft)left=left-selectorWidth+triggerWidth;selector.css({top:top,left:left}).fadeIn(100);selector.on('selectstart',function(){return false});if(!$.browser.msie||($.browser.msie&&$.browser.version>=9)){$(window).on('resize.miniColors',function(event){hide(input)})}$(document).on('mousedown.miniColors touchstart.miniColors',function(event){input.data('mousebutton',1);var testSubject=$(event.target).parents().andSelf();if(testSubject.hasClass('miniColors-colors')){event.preventDefault();input.data('moving','colors');moveColor(input,event)}if(testSubject.hasClass('miniColors-hues')){event.preventDefault();input.data('moving','hues');moveHue(input,event)}if(testSubject.hasClass('miniColors-selector')){event.preventDefault();return}if(testSubject.hasClass('miniColors'))return;hide(input)});$(document).on('mouseup.miniColors touchend.miniColors',function(event){event.preventDefault();input.data('mousebutton',0).removeData('moving')}).on('mousemove.miniColors touchmove.miniColors',function(event){event.preventDefault();if(input.data('mousebutton')===1){if(input.data('moving')==='colors')moveColor(input,event);if(input.data('moving')==='hues')moveHue(input,event)}});if(input.data('open')){input.data('open').call(input.get(0),'#'+hsb2hex(hsb),hsb2rgb(hsb))}};var hide=function(input){if(!input)input=$('.miniColors');input.each(function(){var selector=$(this).data('selector');$(this).removeData('selector');$(selector).fadeOut(100,function(){if(input.data('close')){var hsb=input.data('hsb'),hex=hsb2hex(hsb);input.data('close').call(input.get(0),'#'+hex,hsb2rgb(hsb))}$(this).remove()})});$(document).off('.miniColors')};var moveColor=function(input,event){var colorPicker=input.data('colorPicker');colorPicker.hide();var position={x:event.pageX,y:event.pageY};if(event.originalEvent.changedTouches){position.x=event.originalEvent.changedTouches[0].pageX;position.y=event.originalEvent.changedTouches[0].pageY}position.x=position.x-input.data('selector').find('.miniColors-colors').offset().left-5;position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-5;if(position.x<=-5)position.x=-5;if(position.x>=144)position.x=144;if(position.y<=-5)position.y=-5;if(position.y>=144)position.y=144;input.data('colorPosition',position);colorPicker.css('left',position.x).css('top',position.y).show();var s=Math.round((position.x+5)*0.67);if(s<0)s=0;if(s>100)s=100;var b=100-Math.round((position.y+5)*0.67);if(b<0)b=0;if(b>100)b=100;var hsb=input.data('hsb');hsb.s=s;hsb.b=b;setColor(input,hsb,true)};var moveHue=function(input,event){var huePicker=input.data('huePicker');huePicker.hide();var position={y:event.pageY};if(event.originalEvent.changedTouches){position.y=event.originalEvent.changedTouches[0].pageY}position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-1;if(position.y<=-1)position.y=-1;if(position.y>=149)position.y=149;input.data('huePosition',position);huePicker.css('top',position.y).show();var h=Math.round((150-position.y-1)*2.4);if(h<0)h=0;if(h>360)h=360;var hsb=input.data('hsb');hsb.h=h;setColor(input,hsb,true)};var setColor=function(input,hsb,updateInput){input.data('hsb',hsb);var hex=hsb2hex(hsb);if(updateInput)input.val('#'+convertCase(hex,input.data('letterCase'))).trigger('change');input.data('trigger').css('backgroundColor','#'+hex);if(input.data('selector'))input.data('selector').find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));if(input.data('change')){if(hex===input.data('lastChange'))return;input.data('change').call(input.get(0),'#'+hex,hsb2rgb(hsb));input.data('lastChange',hex)}};var setColorFromInput=function(input){input.val('#'+cleanHex(input.val())).trigger('change');var hex=expandHex(input.val());if(!hex)return false;var hsb=hex2hsb(hex);var currentHSB=input.data('hsb');if(hsb.h===currentHSB.h&&hsb.s===currentHSB.s&&hsb.b===currentHSB.b)return true;var colorPosition=getColorPositionFromHSB(hsb);var colorPicker=$(input.data('colorPicker'));colorPicker.css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');input.data('colorPosition',colorPosition);var huePosition=getHuePositionFromHSB(hsb);var huePicker=$(input.data('huePicker'));huePicker.css('top',huePosition.y+'px');input.data('huePosition',huePosition);setColor(input,hsb);return true};var convertCase=function(string,letterCase){if(letterCase==='lowercase')return string.toLowerCase();if(letterCase==='uppercase')return string.toUpperCase();return string};var getColorPositionFromHSB=function(hsb){var x=Math.ceil(hsb.s/0.67);if(x<0)x=0;if(x>150)x=150;var y=150-Math.ceil(hsb.b/0.67);if(y<0)y=0;if(y>150)y=150;return{x:x-5,y:y-5}};var getHuePositionFromHSB=function(hsb){var y=150-(hsb.h/2.4);if(y<0)h=0;if(y>150)h=150;return{y:y-1}};var cleanHex=function(hex){return hex.replace(/[^A-F0-9]/ig,'')};var expandHex=function(hex){hex=cleanHex(hex);if(!hex)return null;if(hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];return hex.length===6?hex:null};var hsb2rgb=function(hsb){var rgb={};var h=Math.round(hsb.h);var s=Math.round(hsb.s*255/100);var v=Math.round(hsb.b*255/100);if(s===0){rgb.r=rgb.g=rgb.b=v}else{var t1=v;var t2=(255-s)*v/255;var t3=(t1-t2)*(h%60)/60;if(h===360)h=0;if(h<60){rgb.r=t1;rgb.b=t2;rgb.g=t2+t3}else if(h<120){rgb.g=t1;rgb.b=t2;rgb.r=t1-t3}else if(h<180){rgb.g=t1;rgb.r=t2;rgb.b=t2+t3}else if(h<240){rgb.b=t1;rgb.r=t2;rgb.g=t1-t3}else if(h<300){rgb.b=t1;rgb.g=t2;rgb.r=t2+t3}else if(h<360){rgb.r=t1;rgb.g=t2;rgb.b=t1-t3}else{rgb.r=0;rgb.g=0;rgb.b=0}}return{r:Math.round(rgb.r),g:Math.round(rgb.g),b:Math.round(rgb.b)}};var rgb2hex=function(rgb){var hex=[rgb.r.toString(16),rgb.g.toString(16),rgb.b.toString(16)];$.each(hex,function(nr,val){if(val.length===1)hex[nr]='0'+val});return hex.join('')};var hex2rgb=function(hex){hex=parseInt(((hex.indexOf('#')>-1)?hex.substring(1):hex),16);return{r:hex>>16,g:(hex&0x00FF00)>>8,b:(hex&0x0000FF)}};var rgb2hsb=function(rgb){var hsb={h:0,s:0,b:0};var min=Math.min(rgb.r,rgb.g,rgb.b);var max=Math.max(rgb.r,rgb.g,rgb.b);var delta=max-min;hsb.b=max;hsb.s=max!==0?255*delta/max:0;if(hsb.s!==0){if(rgb.r===max){hsb.h=(rgb.g-rgb.b)/delta}else if(rgb.g===max){hsb.h=2+(rgb.b-rgb.r)/delta}else{hsb.h=4+(rgb.r-rgb.g)/delta}}else{hsb.h=-1}hsb.h*=60;if(hsb.h<0){hsb.h+=360}hsb.s*=100/255;hsb.b*=100/255;return hsb};var hex2hsb=function(hex){var hsb=rgb2hsb(hex2rgb(hex));if(hsb.s===0)hsb.h=360;return hsb};var hsb2hex=function(hsb){return rgb2hex(hsb2rgb(hsb))};switch(o){case'readonly':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).prop('readonly',data)});return $(this);case'disabled':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;if(data){disable($(this))}else{enable($(this))}});return $(this);case'value':if(data===undefined){if(!$(this).hasClass('miniColors'))return;var input=$(this),hex=expandHex(input.val());return hex?'#'+convertCase(hex,input.data('letterCase')):null}$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).val(data).trigger('change');setColorFromInput($(this))});return $(this);case'destroy':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;destroy($(this))});return $(this);default:if(!o)o={};$(this).each(function(){if($(this)[0].tagName.toLowerCase()!=='input')return;if($(this).data('trigger'))return;create($(this),o,data)});return $(this)}}})})(jQuery);
10
  function color_picker_init(){
11
  jQuery('.minicolor-picker').miniColors();
12
  }
fields/date_picker/css/datepicker.css CHANGED
@@ -9,13 +9,11 @@
9
  */
10
  .datepicker {
11
  padding: 4px;
12
- -webkit-border-radius: 4px;
13
- -moz-border-radius: 4px;
14
  border-radius: 4px;
15
  direction: ltr;
16
  /*.dow {
17
- border-top: 1px solid #ddd !important;
18
- }*/
19
  }
20
  .datepicker-inline {
21
  width: 220px;
@@ -45,7 +43,7 @@
45
  display: inline-block;
46
  border-left: 6px solid transparent;
47
  border-right: 6px solid transparent;
48
- border-bottom: 6px solid #ffffff;
49
  border-top: 0;
50
  position: absolute;
51
  }
@@ -75,7 +73,7 @@
75
  .datepicker-dropdown.datepicker-orient-bottom:after {
76
  bottom: -6px;
77
  border-bottom: 0;
78
- border-top: 6px solid #ffffff;
79
  }
80
  .datepicker > div {
81
  display: none;
@@ -98,13 +96,11 @@
98
  -ms-user-select: none;
99
  user-select: none;
100
  }
101
- .datepicker td,
102
- .datepicker th {
103
  text-align: center;
104
- width: 20px;
105
- height: 20px;
106
- -webkit-border-radius: 4px;
107
- -moz-border-radius: 4px;
108
  border-radius: 4px;
109
  border: none;
110
  }
@@ -131,24 +127,34 @@
131
  .datepicker table tr td.today:hover,
132
  .datepicker table tr td.today.disabled,
133
  .datepicker table tr td.today.disabled:hover {
134
- background-color: #fde19a;
135
- background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
136
- background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
137
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
138
- background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
139
- background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
140
- background-image: linear-gradient(top, #fdd49a, #fdf59a);
141
- background-repeat: repeat-x;
142
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
143
- border-color: #fdf59a #fdf59a #fbed50;
144
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
145
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
146
- color: #000;
147
  }
148
  .datepicker table tr td.today:hover,
149
  .datepicker table tr td.today:hover:hover,
150
  .datepicker table tr td.today.disabled:hover,
151
  .datepicker table tr td.today.disabled:hover:hover,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  .datepicker table tr td.today:active,
153
  .datepicker table tr td.today:hover:active,
154
  .datepicker table tr td.today.disabled:active,
@@ -157,6 +163,12 @@
157
  .datepicker table tr td.today:hover.active,
158
  .datepicker table tr td.today.disabled.active,
159
  .datepicker table tr td.today.disabled:hover.active,
 
 
 
 
 
 
160
  .datepicker table tr td.today.disabled,
161
  .datepicker table tr td.today:hover.disabled,
162
  .datepicker table tr td.today.disabled.disabled,
@@ -164,18 +176,61 @@
164
  .datepicker table tr td.today[disabled],
165
  .datepicker table tr td.today:hover[disabled],
166
  .datepicker table tr td.today.disabled[disabled],
167
- .datepicker table tr td.today.disabled:hover[disabled] {
168
- background-color: #fdf59a;
169
- }
170
- .datepicker table tr td.today:active,
171
- .datepicker table tr td.today:hover:active,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  .datepicker table tr td.today.disabled:active,
173
- .datepicker table tr td.today.disabled:hover:active,
174
- .datepicker table tr td.today.active,
175
- .datepicker table tr td.today:hover.active,
 
 
 
 
 
 
 
 
176
  .datepicker table tr td.today.disabled.active,
177
- .datepicker table tr td.today.disabled:hover.active {
178
- background-color: #fbf069 \9;
 
 
 
 
 
 
 
 
 
 
 
179
  }
180
  .datepicker table tr td.today:hover:hover {
181
  color: #000;
@@ -188,34 +243,41 @@
188
  .datepicker table tr td.range.disabled,
189
  .datepicker table tr td.range.disabled:hover {
190
  background: #eeeeee;
191
- -webkit-border-radius: 0;
192
- -moz-border-radius: 0;
193
  border-radius: 0;
194
  }
195
  .datepicker table tr td.range.today,
196
  .datepicker table tr td.range.today:hover,
197
  .datepicker table tr td.range.today.disabled,
198
  .datepicker table tr td.range.today.disabled:hover {
199
- background-color: #f3d17a;
200
- background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
201
- background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
202
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
203
- background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
204
- background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
205
- background-image: linear-gradient(top, #f3c17a, #f3e97a);
206
- background-repeat: repeat-x;
207
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
208
- border-color: #f3e97a #f3e97a #edde34;
209
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
210
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
211
- -webkit-border-radius: 0;
212
- -moz-border-radius: 0;
213
  border-radius: 0;
214
  }
215
  .datepicker table tr td.range.today:hover,
216
  .datepicker table tr td.range.today:hover:hover,
217
  .datepicker table tr td.range.today.disabled:hover,
218
  .datepicker table tr td.range.today.disabled:hover:hover,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  .datepicker table tr td.range.today:active,
220
  .datepicker table tr td.range.today:hover:active,
221
  .datepicker table tr td.range.today.disabled:active,
@@ -224,6 +286,12 @@
224
  .datepicker table tr td.range.today:hover.active,
225
  .datepicker table tr td.range.today.disabled.active,
226
  .datepicker table tr td.range.today.disabled:hover.active,
 
 
 
 
 
 
227
  .datepicker table tr td.range.today.disabled,
228
  .datepicker table tr td.range.today:hover.disabled,
229
  .datepicker table tr td.range.today.disabled.disabled,
@@ -231,42 +299,79 @@
231
  .datepicker table tr td.range.today[disabled],
232
  .datepicker table tr td.range.today:hover[disabled],
233
  .datepicker table tr td.range.today.disabled[disabled],
234
- .datepicker table tr td.range.today.disabled:hover[disabled] {
235
- background-color: #f3e97a;
236
- }
237
- .datepicker table tr td.range.today:active,
238
- .datepicker table tr td.range.today:hover:active,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  .datepicker table tr td.range.today.disabled:active,
240
- .datepicker table tr td.range.today.disabled:hover:active,
241
- .datepicker table tr td.range.today.active,
242
- .datepicker table tr td.range.today:hover.active,
 
 
 
 
 
 
 
 
243
  .datepicker table tr td.range.today.disabled.active,
244
- .datepicker table tr td.range.today.disabled:hover.active {
245
- background-color: #efe24b \9;
 
 
 
 
 
 
 
 
 
 
 
246
  }
247
  .datepicker table tr td.selected,
248
  .datepicker table tr td.selected:hover,
249
  .datepicker table tr td.selected.disabled,
250
  .datepicker table tr td.selected.disabled:hover {
251
- background-color: #9e9e9e;
252
- background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
253
- background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
254
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
255
- background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
256
- background-image: -o-linear-gradient(top, #b3b3b3, #808080);
257
- background-image: linear-gradient(top, #b3b3b3, #808080);
258
- background-repeat: repeat-x;
259
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
260
- border-color: #808080 #808080 #595959;
261
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
262
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
263
- color: #fff;
264
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
265
  }
266
  .datepicker table tr td.selected:hover,
267
  .datepicker table tr td.selected:hover:hover,
268
  .datepicker table tr td.selected.disabled:hover,
269
  .datepicker table tr td.selected.disabled:hover:hover,
 
 
 
 
270
  .datepicker table tr td.selected:active,
271
  .datepicker table tr td.selected:hover:active,
272
  .datepicker table tr td.selected.disabled:active,
@@ -275,6 +380,28 @@
275
  .datepicker table tr td.selected:hover.active,
276
  .datepicker table tr td.selected.disabled.active,
277
  .datepicker table tr td.selected.disabled:hover.active,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  .datepicker table tr td.selected.disabled,
279
  .datepicker table tr td.selected:hover.disabled,
280
  .datepicker table tr td.selected.disabled.disabled,
@@ -282,42 +409,79 @@
282
  .datepicker table tr td.selected[disabled],
283
  .datepicker table tr td.selected:hover[disabled],
284
  .datepicker table tr td.selected.disabled[disabled],
285
- .datepicker table tr td.selected.disabled:hover[disabled] {
286
- background-color: #808080;
287
- }
288
- .datepicker table tr td.selected:active,
289
- .datepicker table tr td.selected:hover:active,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  .datepicker table tr td.selected.disabled:active,
291
- .datepicker table tr td.selected.disabled:hover:active,
292
- .datepicker table tr td.selected.active,
293
- .datepicker table tr td.selected:hover.active,
 
 
 
 
 
 
 
 
294
  .datepicker table tr td.selected.disabled.active,
295
- .datepicker table tr td.selected.disabled:hover.active {
296
- background-color: #666666 \9;
 
 
 
 
 
 
 
 
 
 
 
297
  }
298
  .datepicker table tr td.active,
299
  .datepicker table tr td.active:hover,
300
  .datepicker table tr td.active.disabled,
301
  .datepicker table tr td.active.disabled:hover {
302
- background-color: #006dcc;
303
- background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
304
- background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
305
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
306
- background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
307
- background-image: -o-linear-gradient(top, #0088cc, #0044cc);
308
- background-image: linear-gradient(top, #0088cc, #0044cc);
309
- background-repeat: repeat-x;
310
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
311
- border-color: #0044cc #0044cc #002a80;
312
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
313
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
314
- color: #fff;
315
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
316
  }
317
  .datepicker table tr td.active:hover,
318
  .datepicker table tr td.active:hover:hover,
319
  .datepicker table tr td.active.disabled:hover,
320
  .datepicker table tr td.active.disabled:hover:hover,
 
 
 
 
321
  .datepicker table tr td.active:active,
322
  .datepicker table tr td.active:hover:active,
323
  .datepicker table tr td.active.disabled:active,
@@ -326,6 +490,28 @@
326
  .datepicker table tr td.active:hover.active,
327
  .datepicker table tr td.active.disabled.active,
328
  .datepicker table tr td.active.disabled:hover.active,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
  .datepicker table tr td.active.disabled,
330
  .datepicker table tr td.active:hover.disabled,
331
  .datepicker table tr td.active.disabled.disabled,
@@ -333,18 +519,61 @@
333
  .datepicker table tr td.active[disabled],
334
  .datepicker table tr td.active:hover[disabled],
335
  .datepicker table tr td.active.disabled[disabled],
336
- .datepicker table tr td.active.disabled:hover[disabled] {
337
- background-color: #0044cc;
338
- }
339
- .datepicker table tr td.active:active,
340
- .datepicker table tr td.active:hover:active,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
  .datepicker table tr td.active.disabled:active,
342
- .datepicker table tr td.active.disabled:hover:active,
343
- .datepicker table tr td.active.active,
344
- .datepicker table tr td.active:hover.active,
 
 
 
 
 
 
 
 
345
  .datepicker table tr td.active.disabled.active,
346
- .datepicker table tr td.active.disabled:hover.active {
347
- background-color: #003399 \9;
 
 
 
 
 
 
 
 
 
 
 
348
  }
349
  .datepicker table tr td span {
350
  display: block;
@@ -354,8 +583,6 @@
354
  float: left;
355
  margin: 1%;
356
  cursor: pointer;
357
- -webkit-border-radius: 4px;
358
- -moz-border-radius: 4px;
359
  border-radius: 4px;
360
  }
361
  .datepicker table tr td span:hover {
@@ -371,25 +598,35 @@
371
  .datepicker table tr td span.active:hover,
372
  .datepicker table tr td span.active.disabled,
373
  .datepicker table tr td span.active.disabled:hover {
374
- background-color: #006dcc;
375
- background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
376
- background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
377
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
378
- background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
379
- background-image: -o-linear-gradient(top, #0088cc, #0044cc);
380
- background-image: linear-gradient(top, #0088cc, #0044cc);
381
- background-repeat: repeat-x;
382
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
383
- border-color: #0044cc #0044cc #002a80;
384
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
385
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
386
- color: #fff;
387
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
388
  }
389
  .datepicker table tr td span.active:hover,
390
  .datepicker table tr td span.active:hover:hover,
391
  .datepicker table tr td span.active.disabled:hover,
392
  .datepicker table tr td span.active.disabled:hover:hover,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  .datepicker table tr td span.active:active,
394
  .datepicker table tr td span.active:hover:active,
395
  .datepicker table tr td span.active.disabled:active,
@@ -398,6 +635,12 @@
398
  .datepicker table tr td span.active:hover.active,
399
  .datepicker table tr td span.active.disabled.active,
400
  .datepicker table tr td span.active.disabled:hover.active,
 
 
 
 
 
 
401
  .datepicker table tr td span.active.disabled,
402
  .datepicker table tr td span.active:hover.disabled,
403
  .datepicker table tr td span.active.disabled.disabled,
@@ -405,18 +648,61 @@
405
  .datepicker table tr td span.active[disabled],
406
  .datepicker table tr td span.active:hover[disabled],
407
  .datepicker table tr td span.active.disabled[disabled],
408
- .datepicker table tr td span.active.disabled:hover[disabled] {
409
- background-color: #0044cc;
410
- }
411
- .datepicker table tr td span.active:active,
412
- .datepicker table tr td span.active:hover:active,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  .datepicker table tr td span.active.disabled:active,
414
- .datepicker table tr td span.active.disabled:hover:active,
415
- .datepicker table tr td span.active.active,
416
- .datepicker table tr td span.active:hover.active,
 
 
 
 
 
 
 
 
417
  .datepicker table tr td span.active.disabled.active,
418
- .datepicker table tr td span.active.disabled:hover.active {
419
- background-color: #003399 \9;
 
 
 
 
 
 
 
 
 
 
 
420
  }
421
  .datepicker table tr td span.old,
422
  .datepicker table tr td span.new {
@@ -443,8 +729,7 @@
443
  cursor: default;
444
  background-color: transparent;
445
  }
446
- .input-append.date .add-on i,
447
- .input-prepend.date .add-on i {
448
  cursor: pointer;
449
  width: 16px;
450
  height: 16px;
@@ -453,28 +738,23 @@
453
  text-align: center;
454
  }
455
  .input-daterange input:first-child {
456
- -webkit-border-radius: 3px 0 0 3px;
457
- -moz-border-radius: 3px 0 0 3px;
458
  border-radius: 3px 0 0 3px;
459
  }
460
  .input-daterange input:last-child {
461
- -webkit-border-radius: 0 3px 3px 0;
462
- -moz-border-radius: 0 3px 3px 0;
463
  border-radius: 0 3px 3px 0;
464
  }
465
- .input-daterange .add-on {
466
- display: inline-block;
467
  width: auto;
468
  min-width: 16px;
469
- height: 20px;
470
  padding: 4px 5px;
471
  font-weight: normal;
472
- line-height: 20px;
473
  text-align: center;
474
- text-shadow: 0 1px 0 #ffffff;
475
  vertical-align: middle;
476
  background-color: #eeeeee;
477
- border: 1px solid #ccc;
 
478
  margin-left: -5px;
479
  margin-right: -5px;
480
  }
@@ -490,8 +770,6 @@
490
  background-color: #ffffff;
491
  border: 1px solid #ccc;
492
  border: 1px solid rgba(0, 0, 0, 0.2);
493
- -webkit-border-radius: 5px;
494
- -moz-border-radius: 5px;
495
  border-radius: 5px;
496
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
497
  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
@@ -504,11 +782,9 @@
504
  color: #333333;
505
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
506
  font-size: 13px;
507
- line-height: 20px;
508
  }
509
  .datepicker.dropdown-menu th,
510
- .datepicker.datepicker-inline th,
511
- .datepicker.dropdown-menu td,
512
- .datepicker.datepicker-inline td {
513
  padding: 4px 5px;
514
  }
9
  */
10
  .datepicker {
11
  padding: 4px;
 
 
12
  border-radius: 4px;
13
  direction: ltr;
14
  /*.dow {
15
+ border-top: 1px solid #ddd !important;
16
+ }*/
17
  }
18
  .datepicker-inline {
19
  width: 220px;
43
  display: inline-block;
44
  border-left: 6px solid transparent;
45
  border-right: 6px solid transparent;
46
+ border-bottom: 6px solid #fff;
47
  border-top: 0;
48
  position: absolute;
49
  }
73
  .datepicker-dropdown.datepicker-orient-bottom:after {
74
  bottom: -6px;
75
  border-bottom: 0;
76
+ border-top: 6px solid #fff;
77
  }
78
  .datepicker > div {
79
  display: none;
96
  -ms-user-select: none;
97
  user-select: none;
98
  }
99
+ .datepicker table tr td,
100
+ .datepicker table tr th {
101
  text-align: center;
102
+ width: 10px;
103
+ height: 10px;
 
 
104
  border-radius: 4px;
105
  border: none;
106
  }
127
  .datepicker table tr td.today:hover,
128
  .datepicker table tr td.today.disabled,
129
  .datepicker table tr td.today.disabled:hover {
130
+ color: #000000;
131
+ background-color: #ffdb99;
132
+ border-color: #ffb733;
 
 
 
 
 
 
 
 
 
 
133
  }
134
  .datepicker table tr td.today:hover,
135
  .datepicker table tr td.today:hover:hover,
136
  .datepicker table tr td.today.disabled:hover,
137
  .datepicker table tr td.today.disabled:hover:hover,
138
+ .datepicker table tr td.today:focus,
139
+ .datepicker table tr td.today:hover:focus,
140
+ .datepicker table tr td.today.disabled:focus,
141
+ .datepicker table tr td.today.disabled:hover:focus,
142
+ .datepicker table tr td.today:active,
143
+ .datepicker table tr td.today:hover:active,
144
+ .datepicker table tr td.today.disabled:active,
145
+ .datepicker table tr td.today.disabled:hover:active,
146
+ .datepicker table tr td.today.active,
147
+ .datepicker table tr td.today:hover.active,
148
+ .datepicker table tr td.today.disabled.active,
149
+ .datepicker table tr td.today.disabled:hover.active,
150
+ .open .dropdown-toggle.datepicker table tr td.today,
151
+ .open .dropdown-toggle.datepicker table tr td.today:hover,
152
+ .open .dropdown-toggle.datepicker table tr td.today.disabled,
153
+ .open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
154
+ color: #000000;
155
+ background-color: #ffcd70;
156
+ border-color: #f59e00;
157
+ }
158
  .datepicker table tr td.today:active,
159
  .datepicker table tr td.today:hover:active,
160
  .datepicker table tr td.today.disabled:active,
163
  .datepicker table tr td.today:hover.active,
164
  .datepicker table tr td.today.disabled.active,
165
  .datepicker table tr td.today.disabled:hover.active,
166
+ .open .dropdown-toggle.datepicker table tr td.today,
167
+ .open .dropdown-toggle.datepicker table tr td.today:hover,
168
+ .open .dropdown-toggle.datepicker table tr td.today.disabled,
169
+ .open .dropdown-toggle.datepicker table tr td.today.disabled:hover {
170
+ background-image: none;
171
+ }
172
  .datepicker table tr td.today.disabled,
173
  .datepicker table tr td.today:hover.disabled,
174
  .datepicker table tr td.today.disabled.disabled,
176
  .datepicker table tr td.today[disabled],
177
  .datepicker table tr td.today:hover[disabled],
178
  .datepicker table tr td.today.disabled[disabled],
179
+ .datepicker table tr td.today.disabled:hover[disabled],
180
+ fieldset[disabled] .datepicker table tr td.today,
181
+ fieldset[disabled] .datepicker table tr td.today:hover,
182
+ fieldset[disabled] .datepicker table tr td.today.disabled,
183
+ fieldset[disabled] .datepicker table tr td.today.disabled:hover,
184
+ .datepicker table tr td.today.disabled:hover,
185
+ .datepicker table tr td.today:hover.disabled:hover,
186
+ .datepicker table tr td.today.disabled.disabled:hover,
187
+ .datepicker table tr td.today.disabled:hover.disabled:hover,
188
+ .datepicker table tr td.today[disabled]:hover,
189
+ .datepicker table tr td.today:hover[disabled]:hover,
190
+ .datepicker table tr td.today.disabled[disabled]:hover,
191
+ .datepicker table tr td.today.disabled:hover[disabled]:hover,
192
+ fieldset[disabled] .datepicker table tr td.today:hover,
193
+ fieldset[disabled] .datepicker table tr td.today:hover:hover,
194
+ fieldset[disabled] .datepicker table tr td.today.disabled:hover,
195
+ fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,
196
+ .datepicker table tr td.today.disabled:focus,
197
+ .datepicker table tr td.today:hover.disabled:focus,
198
+ .datepicker table tr td.today.disabled.disabled:focus,
199
+ .datepicker table tr td.today.disabled:hover.disabled:focus,
200
+ .datepicker table tr td.today[disabled]:focus,
201
+ .datepicker table tr td.today:hover[disabled]:focus,
202
+ .datepicker table tr td.today.disabled[disabled]:focus,
203
+ .datepicker table tr td.today.disabled:hover[disabled]:focus,
204
+ fieldset[disabled] .datepicker table tr td.today:focus,
205
+ fieldset[disabled] .datepicker table tr td.today:hover:focus,
206
+ fieldset[disabled] .datepicker table tr td.today.disabled:focus,
207
+ fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,
208
  .datepicker table tr td.today.disabled:active,
209
+ .datepicker table tr td.today:hover.disabled:active,
210
+ .datepicker table tr td.today.disabled.disabled:active,
211
+ .datepicker table tr td.today.disabled:hover.disabled:active,
212
+ .datepicker table tr td.today[disabled]:active,
213
+ .datepicker table tr td.today:hover[disabled]:active,
214
+ .datepicker table tr td.today.disabled[disabled]:active,
215
+ .datepicker table tr td.today.disabled:hover[disabled]:active,
216
+ fieldset[disabled] .datepicker table tr td.today:active,
217
+ fieldset[disabled] .datepicker table tr td.today:hover:active,
218
+ fieldset[disabled] .datepicker table tr td.today.disabled:active,
219
+ fieldset[disabled] .datepicker table tr td.today.disabled:hover:active,
220
  .datepicker table tr td.today.disabled.active,
221
+ .datepicker table tr td.today:hover.disabled.active,
222
+ .datepicker table tr td.today.disabled.disabled.active,
223
+ .datepicker table tr td.today.disabled:hover.disabled.active,
224
+ .datepicker table tr td.today[disabled].active,
225
+ .datepicker table tr td.today:hover[disabled].active,
226
+ .datepicker table tr td.today.disabled[disabled].active,
227
+ .datepicker table tr td.today.disabled:hover[disabled].active,
228
+ fieldset[disabled] .datepicker table tr td.today.active,
229
+ fieldset[disabled] .datepicker table tr td.today:hover.active,
230
+ fieldset[disabled] .datepicker table tr td.today.disabled.active,
231
+ fieldset[disabled] .datepicker table tr td.today.disabled:hover.active {
232
+ background-color: #ffdb99;
233
+ border-color: #ffb733;
234
  }
235
  .datepicker table tr td.today:hover:hover {
236
  color: #000;
243
  .datepicker table tr td.range.disabled,
244
  .datepicker table tr td.range.disabled:hover {
245
  background: #eeeeee;
 
 
246
  border-radius: 0;
247
  }
248
  .datepicker table tr td.range.today,
249
  .datepicker table tr td.range.today:hover,
250
  .datepicker table tr td.range.today.disabled,
251
  .datepicker table tr td.range.today.disabled:hover {
252
+ color: #000000;
253
+ background-color: #f7ca77;
254
+ border-color: #f1a417;
 
 
 
 
 
 
 
 
 
 
 
255
  border-radius: 0;
256
  }
257
  .datepicker table tr td.range.today:hover,
258
  .datepicker table tr td.range.today:hover:hover,
259
  .datepicker table tr td.range.today.disabled:hover,
260
  .datepicker table tr td.range.today.disabled:hover:hover,
261
+ .datepicker table tr td.range.today:focus,
262
+ .datepicker table tr td.range.today:hover:focus,
263
+ .datepicker table tr td.range.today.disabled:focus,
264
+ .datepicker table tr td.range.today.disabled:hover:focus,
265
+ .datepicker table tr td.range.today:active,
266
+ .datepicker table tr td.range.today:hover:active,
267
+ .datepicker table tr td.range.today.disabled:active,
268
+ .datepicker table tr td.range.today.disabled:hover:active,
269
+ .datepicker table tr td.range.today.active,
270
+ .datepicker table tr td.range.today:hover.active,
271
+ .datepicker table tr td.range.today.disabled.active,
272
+ .datepicker table tr td.range.today.disabled:hover.active,
273
+ .open .dropdown-toggle.datepicker table tr td.range.today,
274
+ .open .dropdown-toggle.datepicker table tr td.range.today:hover,
275
+ .open .dropdown-toggle.datepicker table tr td.range.today.disabled,
276
+ .open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
277
+ color: #000000;
278
+ background-color: #f4bb51;
279
+ border-color: #bf800c;
280
+ }
281
  .datepicker table tr td.range.today:active,
282
  .datepicker table tr td.range.today:hover:active,
283
  .datepicker table tr td.range.today.disabled:active,
286
  .datepicker table tr td.range.today:hover.active,
287
  .datepicker table tr td.range.today.disabled.active,
288
  .datepicker table tr td.range.today.disabled:hover.active,
289
+ .open .dropdown-toggle.datepicker table tr td.range.today,
290
+ .open .dropdown-toggle.datepicker table tr td.range.today:hover,
291
+ .open .dropdown-toggle.datepicker table tr td.range.today.disabled,
292
+ .open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {
293
+ background-image: none;
294
+ }
295
  .datepicker table tr td.range.today.disabled,
296
  .datepicker table tr td.range.today:hover.disabled,
297
  .datepicker table tr td.range.today.disabled.disabled,
299
  .datepicker table tr td.range.today[disabled],
300
  .datepicker table tr td.range.today:hover[disabled],
301
  .datepicker table tr td.range.today.disabled[disabled],
302
+ .datepicker table tr td.range.today.disabled:hover[disabled],
303
+ fieldset[disabled] .datepicker table tr td.range.today,
304
+ fieldset[disabled] .datepicker table tr td.range.today:hover,
305
+ fieldset[disabled] .datepicker table tr td.range.today.disabled,
306
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
307
+ .datepicker table tr td.range.today.disabled:hover,
308
+ .datepicker table tr td.range.today:hover.disabled:hover,
309
+ .datepicker table tr td.range.today.disabled.disabled:hover,
310
+ .datepicker table tr td.range.today.disabled:hover.disabled:hover,
311
+ .datepicker table tr td.range.today[disabled]:hover,
312
+ .datepicker table tr td.range.today:hover[disabled]:hover,
313
+ .datepicker table tr td.range.today.disabled[disabled]:hover,
314
+ .datepicker table tr td.range.today.disabled:hover[disabled]:hover,
315
+ fieldset[disabled] .datepicker table tr td.range.today:hover,
316
+ fieldset[disabled] .datepicker table tr td.range.today:hover:hover,
317
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,
318
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,
319
+ .datepicker table tr td.range.today.disabled:focus,
320
+ .datepicker table tr td.range.today:hover.disabled:focus,
321
+ .datepicker table tr td.range.today.disabled.disabled:focus,
322
+ .datepicker table tr td.range.today.disabled:hover.disabled:focus,
323
+ .datepicker table tr td.range.today[disabled]:focus,
324
+ .datepicker table tr td.range.today:hover[disabled]:focus,
325
+ .datepicker table tr td.range.today.disabled[disabled]:focus,
326
+ .datepicker table tr td.range.today.disabled:hover[disabled]:focus,
327
+ fieldset[disabled] .datepicker table tr td.range.today:focus,
328
+ fieldset[disabled] .datepicker table tr td.range.today:hover:focus,
329
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:focus,
330
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,
331
  .datepicker table tr td.range.today.disabled:active,
332
+ .datepicker table tr td.range.today:hover.disabled:active,
333
+ .datepicker table tr td.range.today.disabled.disabled:active,
334
+ .datepicker table tr td.range.today.disabled:hover.disabled:active,
335
+ .datepicker table tr td.range.today[disabled]:active,
336
+ .datepicker table tr td.range.today:hover[disabled]:active,
337
+ .datepicker table tr td.range.today.disabled[disabled]:active,
338
+ .datepicker table tr td.range.today.disabled:hover[disabled]:active,
339
+ fieldset[disabled] .datepicker table tr td.range.today:active,
340
+ fieldset[disabled] .datepicker table tr td.range.today:hover:active,
341
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:active,
342
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,
343
  .datepicker table tr td.range.today.disabled.active,
344
+ .datepicker table tr td.range.today:hover.disabled.active,
345
+ .datepicker table tr td.range.today.disabled.disabled.active,
346
+ .datepicker table tr td.range.today.disabled:hover.disabled.active,
347
+ .datepicker table tr td.range.today[disabled].active,
348
+ .datepicker table tr td.range.today:hover[disabled].active,
349
+ .datepicker table tr td.range.today.disabled[disabled].active,
350
+ .datepicker table tr td.range.today.disabled:hover[disabled].active,
351
+ fieldset[disabled] .datepicker table tr td.range.today.active,
352
+ fieldset[disabled] .datepicker table tr td.range.today:hover.active,
353
+ fieldset[disabled] .datepicker table tr td.range.today.disabled.active,
354
+ fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {
355
+ background-color: #f7ca77;
356
+ border-color: #f1a417;
357
  }
358
  .datepicker table tr td.selected,
359
  .datepicker table tr td.selected:hover,
360
  .datepicker table tr td.selected.disabled,
361
  .datepicker table tr td.selected.disabled:hover {
362
+ color: #ffffff;
363
+ background-color: #999999;
364
+ border-color: #555555;
 
 
 
 
 
 
 
 
 
 
365
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
366
  }
367
  .datepicker table tr td.selected:hover,
368
  .datepicker table tr td.selected:hover:hover,
369
  .datepicker table tr td.selected.disabled:hover,
370
  .datepicker table tr td.selected.disabled:hover:hover,
371
+ .datepicker table tr td.selected:focus,
372
+ .datepicker table tr td.selected:hover:focus,
373
+ .datepicker table tr td.selected.disabled:focus,
374
+ .datepicker table tr td.selected.disabled:hover:focus,
375
  .datepicker table tr td.selected:active,
376
  .datepicker table tr td.selected:hover:active,
377
  .datepicker table tr td.selected.disabled:active,
380
  .datepicker table tr td.selected:hover.active,
381
  .datepicker table tr td.selected.disabled.active,
382
  .datepicker table tr td.selected.disabled:hover.active,
383
+ .open .dropdown-toggle.datepicker table tr td.selected,
384
+ .open .dropdown-toggle.datepicker table tr td.selected:hover,
385
+ .open .dropdown-toggle.datepicker table tr td.selected.disabled,
386
+ .open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
387
+ color: #ffffff;
388
+ background-color: #858585;
389
+ border-color: #373737;
390
+ }
391
+ .datepicker table tr td.selected:active,
392
+ .datepicker table tr td.selected:hover:active,
393
+ .datepicker table tr td.selected.disabled:active,
394
+ .datepicker table tr td.selected.disabled:hover:active,
395
+ .datepicker table tr td.selected.active,
396
+ .datepicker table tr td.selected:hover.active,
397
+ .datepicker table tr td.selected.disabled.active,
398
+ .datepicker table tr td.selected.disabled:hover.active,
399
+ .open .dropdown-toggle.datepicker table tr td.selected,
400
+ .open .dropdown-toggle.datepicker table tr td.selected:hover,
401
+ .open .dropdown-toggle.datepicker table tr td.selected.disabled,
402
+ .open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {
403
+ background-image: none;
404
+ }
405
  .datepicker table tr td.selected.disabled,
406
  .datepicker table tr td.selected:hover.disabled,
407
  .datepicker table tr td.selected.disabled.disabled,
409
  .datepicker table tr td.selected[disabled],
410
  .datepicker table tr td.selected:hover[disabled],
411
  .datepicker table tr td.selected.disabled[disabled],
412
+ .datepicker table tr td.selected.disabled:hover[disabled],
413
+ fieldset[disabled] .datepicker table tr td.selected,
414
+ fieldset[disabled] .datepicker table tr td.selected:hover,
415
+ fieldset[disabled] .datepicker table tr td.selected.disabled,
416
+ fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
417
+ .datepicker table tr td.selected.disabled:hover,
418
+ .datepicker table tr td.selected:hover.disabled:hover,
419
+ .datepicker table tr td.selected.disabled.disabled:hover,
420
+ .datepicker table tr td.selected.disabled:hover.disabled:hover,
421
+ .datepicker table tr td.selected[disabled]:hover,
422
+ .datepicker table tr td.selected:hover[disabled]:hover,
423
+ .datepicker table tr td.selected.disabled[disabled]:hover,
424
+ .datepicker table tr td.selected.disabled:hover[disabled]:hover,
425
+ fieldset[disabled] .datepicker table tr td.selected:hover,
426
+ fieldset[disabled] .datepicker table tr td.selected:hover:hover,
427
+ fieldset[disabled] .datepicker table tr td.selected.disabled:hover,
428
+ fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,
429
+ .datepicker table tr td.selected.disabled:focus,
430
+ .datepicker table tr td.selected:hover.disabled:focus,
431
+ .datepicker table tr td.selected.disabled.disabled:focus,
432
+ .datepicker table tr td.selected.disabled:hover.disabled:focus,
433
+ .datepicker table tr td.selected[disabled]:focus,
434
+ .datepicker table tr td.selected:hover[disabled]:focus,
435
+ .datepicker table tr td.selected.disabled[disabled]:focus,
436
+ .datepicker table tr td.selected.disabled:hover[disabled]:focus,
437
+ fieldset[disabled] .datepicker table tr td.selected:focus,
438
+ fieldset[disabled] .datepicker table tr td.selected:hover:focus,
439
+ fieldset[disabled] .datepicker table tr td.selected.disabled:focus,
440
+ fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,
441
  .datepicker table tr td.selected.disabled:active,
442
+ .datepicker table tr td.selected:hover.disabled:active,
443
+ .datepicker table tr td.selected.disabled.disabled:active,
444
+ .datepicker table tr td.selected.disabled:hover.disabled:active,
445
+ .datepicker table tr td.selected[disabled]:active,
446
+ .datepicker table tr td.selected:hover[disabled]:active,
447
+ .datepicker table tr td.selected.disabled[disabled]:active,
448
+ .datepicker table tr td.selected.disabled:hover[disabled]:active,
449
+ fieldset[disabled] .datepicker table tr td.selected:active,
450
+ fieldset[disabled] .datepicker table tr td.selected:hover:active,
451
+ fieldset[disabled] .datepicker table tr td.selected.disabled:active,
452
+ fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,
453
  .datepicker table tr td.selected.disabled.active,
454
+ .datepicker table tr td.selected:hover.disabled.active,
455
+ .datepicker table tr td.selected.disabled.disabled.active,
456
+ .datepicker table tr td.selected.disabled:hover.disabled.active,
457
+ .datepicker table tr td.selected[disabled].active,
458
+ .datepicker table tr td.selected:hover[disabled].active,
459
+ .datepicker table tr td.selected.disabled[disabled].active,
460
+ .datepicker table tr td.selected.disabled:hover[disabled].active,
461
+ fieldset[disabled] .datepicker table tr td.selected.active,
462
+ fieldset[disabled] .datepicker table tr td.selected:hover.active,
463
+ fieldset[disabled] .datepicker table tr td.selected.disabled.active,
464
+ fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {
465
+ background-color: #999999;
466
+ border-color: #555555;
467
  }
468
  .datepicker table tr td.active,
469
  .datepicker table tr td.active:hover,
470
  .datepicker table tr td.active.disabled,
471
  .datepicker table tr td.active.disabled:hover {
472
+ color: #ffffff;
473
+ background-color: #428bca;
474
+ border-color: #357ebd;
 
 
 
 
 
 
 
 
 
 
475
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
476
  }
477
  .datepicker table tr td.active:hover,
478
  .datepicker table tr td.active:hover:hover,
479
  .datepicker table tr td.active.disabled:hover,
480
  .datepicker table tr td.active.disabled:hover:hover,
481
+ .datepicker table tr td.active:focus,
482
+ .datepicker table tr td.active:hover:focus,
483
+ .datepicker table tr td.active.disabled:focus,
484
+ .datepicker table tr td.active.disabled:hover:focus,
485
  .datepicker table tr td.active:active,
486
  .datepicker table tr td.active:hover:active,
487
  .datepicker table tr td.active.disabled:active,
490
  .datepicker table tr td.active:hover.active,
491
  .datepicker table tr td.active.disabled.active,
492
  .datepicker table tr td.active.disabled:hover.active,
493
+ .open .dropdown-toggle.datepicker table tr td.active,
494
+ .open .dropdown-toggle.datepicker table tr td.active:hover,
495
+ .open .dropdown-toggle.datepicker table tr td.active.disabled,
496
+ .open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
497
+ color: #ffffff;
498
+ background-color: #3276b1;
499
+ border-color: #285e8e;
500
+ }
501
+ .datepicker table tr td.active:active,
502
+ .datepicker table tr td.active:hover:active,
503
+ .datepicker table tr td.active.disabled:active,
504
+ .datepicker table tr td.active.disabled:hover:active,
505
+ .datepicker table tr td.active.active,
506
+ .datepicker table tr td.active:hover.active,
507
+ .datepicker table tr td.active.disabled.active,
508
+ .datepicker table tr td.active.disabled:hover.active,
509
+ .open .dropdown-toggle.datepicker table tr td.active,
510
+ .open .dropdown-toggle.datepicker table tr td.active:hover,
511
+ .open .dropdown-toggle.datepicker table tr td.active.disabled,
512
+ .open .dropdown-toggle.datepicker table tr td.active.disabled:hover {
513
+ background-image: none;
514
+ }
515
  .datepicker table tr td.active.disabled,
516
  .datepicker table tr td.active:hover.disabled,
517
  .datepicker table tr td.active.disabled.disabled,
519
  .datepicker table tr td.active[disabled],
520
  .datepicker table tr td.active:hover[disabled],
521
  .datepicker table tr td.active.disabled[disabled],
522
+ .datepicker table tr td.active.disabled:hover[disabled],
523
+ fieldset[disabled] .datepicker table tr td.active,
524
+ fieldset[disabled] .datepicker table tr td.active:hover,
525
+ fieldset[disabled] .datepicker table tr td.active.disabled,
526
+ fieldset[disabled] .datepicker table tr td.active.disabled:hover,
527
+ .datepicker table tr td.active.disabled:hover,
528
+ .datepicker table tr td.active:hover.disabled:hover,
529
+ .datepicker table tr td.active.disabled.disabled:hover,
530
+ .datepicker table tr td.active.disabled:hover.disabled:hover,
531
+ .datepicker table tr td.active[disabled]:hover,
532
+ .datepicker table tr td.active:hover[disabled]:hover,
533
+ .datepicker table tr td.active.disabled[disabled]:hover,
534
+ .datepicker table tr td.active.disabled:hover[disabled]:hover,
535
+ fieldset[disabled] .datepicker table tr td.active:hover,
536
+ fieldset[disabled] .datepicker table tr td.active:hover:hover,
537
+ fieldset[disabled] .datepicker table tr td.active.disabled:hover,
538
+ fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,
539
+ .datepicker table tr td.active.disabled:focus,
540
+ .datepicker table tr td.active:hover.disabled:focus,
541
+ .datepicker table tr td.active.disabled.disabled:focus,
542
+ .datepicker table tr td.active.disabled:hover.disabled:focus,
543
+ .datepicker table tr td.active[disabled]:focus,
544
+ .datepicker table tr td.active:hover[disabled]:focus,
545
+ .datepicker table tr td.active.disabled[disabled]:focus,
546
+ .datepicker table tr td.active.disabled:hover[disabled]:focus,
547
+ fieldset[disabled] .datepicker table tr td.active:focus,
548
+ fieldset[disabled] .datepicker table tr td.active:hover:focus,
549
+ fieldset[disabled] .datepicker table tr td.active.disabled:focus,
550
+ fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,
551
  .datepicker table tr td.active.disabled:active,
552
+ .datepicker table tr td.active:hover.disabled:active,
553
+ .datepicker table tr td.active.disabled.disabled:active,
554
+ .datepicker table tr td.active.disabled:hover.disabled:active,
555
+ .datepicker table tr td.active[disabled]:active,
556
+ .datepicker table tr td.active:hover[disabled]:active,
557
+ .datepicker table tr td.active.disabled[disabled]:active,
558
+ .datepicker table tr td.active.disabled:hover[disabled]:active,
559
+ fieldset[disabled] .datepicker table tr td.active:active,
560
+ fieldset[disabled] .datepicker table tr td.active:hover:active,
561
+ fieldset[disabled] .datepicker table tr td.active.disabled:active,
562
+ fieldset[disabled] .datepicker table tr td.active.disabled:hover:active,
563
  .datepicker table tr td.active.disabled.active,
564
+ .datepicker table tr td.active:hover.disabled.active,
565
+ .datepicker table tr td.active.disabled.disabled.active,
566
+ .datepicker table tr td.active.disabled:hover.disabled.active,
567
+ .datepicker table tr td.active[disabled].active,
568
+ .datepicker table tr td.active:hover[disabled].active,
569
+ .datepicker table tr td.active.disabled[disabled].active,
570
+ .datepicker table tr td.active.disabled:hover[disabled].active,
571
+ fieldset[disabled] .datepicker table tr td.active.active,
572
+ fieldset[disabled] .datepicker table tr td.active:hover.active,
573
+ fieldset[disabled] .datepicker table tr td.active.disabled.active,
574
+ fieldset[disabled] .datepicker table tr td.active.disabled:hover.active {
575
+ background-color: #428bca;
576
+ border-color: #357ebd;
577
  }
578
  .datepicker table tr td span {
579
  display: block;
583
  float: left;
584
  margin: 1%;
585
  cursor: pointer;
 
 
586
  border-radius: 4px;
587
  }
588
  .datepicker table tr td span:hover {
598
  .datepicker table tr td span.active:hover,
599
  .datepicker table tr td span.active.disabled,
600
  .datepicker table tr td span.active.disabled:hover {
601
+ color: #ffffff;
602
+ background-color: #428bca;
603
+ border-color: #357ebd;
 
 
 
 
 
 
 
 
 
 
604
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
605
  }
606
  .datepicker table tr td span.active:hover,
607
  .datepicker table tr td span.active:hover:hover,
608
  .datepicker table tr td span.active.disabled:hover,
609
  .datepicker table tr td span.active.disabled:hover:hover,
610
+ .datepicker table tr td span.active:focus,
611
+ .datepicker table tr td span.active:hover:focus,
612
+ .datepicker table tr td span.active.disabled:focus,
613
+ .datepicker table tr td span.active.disabled:hover:focus,
614
+ .datepicker table tr td span.active:active,
615
+ .datepicker table tr td span.active:hover:active,
616
+ .datepicker table tr td span.active.disabled:active,
617
+ .datepicker table tr td span.active.disabled:hover:active,
618
+ .datepicker table tr td span.active.active,
619
+ .datepicker table tr td span.active:hover.active,
620
+ .datepicker table tr td span.active.disabled.active,
621
+ .datepicker table tr td span.active.disabled:hover.active,
622
+ .open .dropdown-toggle.datepicker table tr td span.active,
623
+ .open .dropdown-toggle.datepicker table tr td span.active:hover,
624
+ .open .dropdown-toggle.datepicker table tr td span.active.disabled,
625
+ .open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
626
+ color: #ffffff;
627
+ background-color: #3276b1;
628
+ border-color: #285e8e;
629
+ }
630
  .datepicker table tr td span.active:active,
631
  .datepicker table tr td span.active:hover:active,
632
  .datepicker table tr td span.active.disabled:active,
635
  .datepicker table tr td span.active:hover.active,
636
  .datepicker table tr td span.active.disabled.active,
637
  .datepicker table tr td span.active.disabled:hover.active,
638
+ .open .dropdown-toggle.datepicker table tr td span.active,
639
+ .open .dropdown-toggle.datepicker table tr td span.active:hover,
640
+ .open .dropdown-toggle.datepicker table tr td span.active.disabled,
641
+ .open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {
642
+ background-image: none;
643
+ }
644
  .datepicker table tr td span.active.disabled,
645
  .datepicker table tr td span.active:hover.disabled,
646
  .datepicker table tr td span.active.disabled.disabled,
648
  .datepicker table tr td span.active[disabled],
649
  .datepicker table tr td span.active:hover[disabled],
650
  .datepicker table tr td span.active.disabled[disabled],
651
+ .datepicker table tr td span.active.disabled:hover[disabled],
652
+ fieldset[disabled] .datepicker table tr td span.active,
653
+ fieldset[disabled] .datepicker table tr td span.active:hover,
654
+ fieldset[disabled] .datepicker table tr td span.active.disabled,
655
+ fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
656
+ .datepicker table tr td span.active.disabled:hover,
657
+ .datepicker table tr td span.active:hover.disabled:hover,
658
+ .datepicker table tr td span.active.disabled.disabled:hover,
659
+ .datepicker table tr td span.active.disabled:hover.disabled:hover,
660
+ .datepicker table tr td span.active[disabled]:hover,
661
+ .datepicker table tr td span.active:hover[disabled]:hover,
662
+ .datepicker table tr td span.active.disabled[disabled]:hover,
663
+ .datepicker table tr td span.active.disabled:hover[disabled]:hover,
664
+ fieldset[disabled] .datepicker table tr td span.active:hover,
665
+ fieldset[disabled] .datepicker table tr td span.active:hover:hover,
666
+ fieldset[disabled] .datepicker table tr td span.active.disabled:hover,
667
+ fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,
668
+ .datepicker table tr td span.active.disabled:focus,
669
+ .datepicker table tr td span.active:hover.disabled:focus,
670
+ .datepicker table tr td span.active.disabled.disabled:focus,
671
+ .datepicker table tr td span.active.disabled:hover.disabled:focus,
672
+ .datepicker table tr td span.active[disabled]:focus,
673
+ .datepicker table tr td span.active:hover[disabled]:focus,
674
+ .datepicker table tr td span.active.disabled[disabled]:focus,
675
+ .datepicker table tr td span.active.disabled:hover[disabled]:focus,
676
+ fieldset[disabled] .datepicker table tr td span.active:focus,
677
+ fieldset[disabled] .datepicker table tr td span.active:hover:focus,
678
+ fieldset[disabled] .datepicker table tr td span.active.disabled:focus,
679
+ fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,
680
  .datepicker table tr td span.active.disabled:active,
681
+ .datepicker table tr td span.active:hover.disabled:active,
682
+ .datepicker table tr td span.active.disabled.disabled:active,
683
+ .datepicker table tr td span.active.disabled:hover.disabled:active,
684
+ .datepicker table tr td span.active[disabled]:active,
685
+ .datepicker table tr td span.active:hover[disabled]:active,
686
+ .datepicker table tr td span.active.disabled[disabled]:active,
687
+ .datepicker table tr td span.active.disabled:hover[disabled]:active,
688
+ fieldset[disabled] .datepicker table tr td span.active:active,
689
+ fieldset[disabled] .datepicker table tr td span.active:hover:active,
690
+ fieldset[disabled] .datepicker table tr td span.active.disabled:active,
691
+ fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,
692
  .datepicker table tr td span.active.disabled.active,
693
+ .datepicker table tr td span.active:hover.disabled.active,
694
+ .datepicker table tr td span.active.disabled.disabled.active,
695
+ .datepicker table tr td span.active.disabled:hover.disabled.active,
696
+ .datepicker table tr td span.active[disabled].active,
697
+ .datepicker table tr td span.active:hover[disabled].active,
698
+ .datepicker table tr td span.active.disabled[disabled].active,
699
+ .datepicker table tr td span.active.disabled:hover[disabled].active,
700
+ fieldset[disabled] .datepicker table tr td span.active.active,
701
+ fieldset[disabled] .datepicker table tr td span.active:hover.active,
702
+ fieldset[disabled] .datepicker table tr td span.active.disabled.active,
703
+ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {
704
+ background-color: #428bca;
705
+ border-color: #357ebd;
706
  }
707
  .datepicker table tr td span.old,
708
  .datepicker table tr td span.new {
729
  cursor: default;
730
  background-color: transparent;
731
  }
732
+ .input-group.date .input-group-addon i {
 
733
  cursor: pointer;
734
  width: 16px;
735
  height: 16px;
738
  text-align: center;
739
  }
740
  .input-daterange input:first-child {
 
 
741
  border-radius: 3px 0 0 3px;
742
  }
743
  .input-daterange input:last-child {
 
 
744
  border-radius: 0 3px 3px 0;
745
  }
746
+ .input-daterange .input-group-addon {
 
747
  width: auto;
748
  min-width: 16px;
 
749
  padding: 4px 5px;
750
  font-weight: normal;
751
+ line-height: 1.42857143;
752
  text-align: center;
753
+ text-shadow: 0 1px 0 #fff;
754
  vertical-align: middle;
755
  background-color: #eeeeee;
756
+ border: solid #cccccc;
757
+ border-width: 1px 0;
758
  margin-left: -5px;
759
  margin-right: -5px;
760
  }
770
  background-color: #ffffff;
771
  border: 1px solid #ccc;
772
  border: 1px solid rgba(0, 0, 0, 0.2);
 
 
773
  border-radius: 5px;
774
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
775
  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
782
  color: #333333;
783
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
784
  font-size: 13px;
785
+ line-height: 1.42857143;
786
  }
787
  .datepicker.dropdown-menu th,
788
+ .datepicker.dropdown-menu td {
 
 
789
  padding: 4px 5px;
790
  }
fields/date_picker/datepicker.php CHANGED
@@ -1,7 +1,7 @@
1
  <div class="<?php echo $field_wrapper_class; ?>">
2
  <?php echo $field_label; ?>
3
  <div class="<?php echo $field_input_class; ?>">
4
- <input <?php echo $field_placeholder; ?> type="text" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?> is-datepicker" id="<?php echo $field_id; ?>" data-date-format="<?php echo $field['config']['format']; ?>" name="<?php echo $field_name; ?>" value="<?php echo $field_value; ?>" <?php echo $field_required; ?>>
5
  <?php echo $field_caption; ?>
6
  </div>
7
  </div>
1
  <div class="<?php echo $field_wrapper_class; ?>">
2
  <?php echo $field_label; ?>
3
  <div class="<?php echo $field_input_class; ?>">
4
+ <input <?php echo $field_placeholder; ?> type="text" data-provide="datepicker" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?> is-datepicker" id="<?php echo $field_id; ?>" data-date-format="<?php echo $field['config']['format']; ?>" name="<?php echo $field_name; ?>" value="<?php echo $field_value; ?>" <?php echo $field_required; ?>>
5
  <?php echo $field_caption; ?>
6
  </div>
7
  </div>
fields/date_picker/js/bootstrap-datepicker.js CHANGED
@@ -1,9 +1,11 @@
1
  /* =========================================================
2
  * bootstrap-datepicker.js
3
- * http://www.eyecon.ro/bootstrap-datepicker
 
 
 
4
  * =========================================================
5
- * Copyright 2012 Stefan Petre
6
- * Improvements by Andrew Rowls
7
  *
8
  * Licensed under the Apache License, Version 2.0 (the "License");
9
  * you may not use this file except in compliance with the License.
@@ -18,120 +20,301 @@
18
  * limitations under the License.
19
  * ========================================================= */
20
 
21
- !function( $ ) {
 
 
22
 
23
  function UTCDate(){
24
  return new Date(Date.UTC.apply(Date, arguments));
25
  }
26
  function UTCToday(){
27
  var today = new Date();
28
- return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate());
 
 
 
 
 
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  // Picker object
32
 
33
- var Datepicker = function(element, options) {
34
- var that = this;
 
 
 
 
35
 
36
  this.element = $(element);
37
- this.language = options.language||this.element.data('date-language')||"en";
38
- this.language = this.language in dates ? this.language : "en";
39
- this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
40
- this.picker = $(DPGlobal.template)
41
- .appendTo('body')
42
- .on({
43
- click: $.proxy(this.click, this)
44
- });
45
  this.isInput = this.element.is('input');
46
- this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
47
  this.hasInput = this.component && this.element.find('input').length;
48
- if(this.component && this.component.length === 0)
49
  this.component = false;
50
 
 
 
51
  this._attachEvents();
52
 
53
- this.forceParse = true;
54
- if ('forceParse' in options) {
55
- this.forceParse = options.forceParse;
56
- } else if ('dateForceParse' in this.element.data()) {
57
- this.forceParse = this.element.data('date-force-parse');
58
  }
59
-
60
- $(document).on('mousedown', function (e) {
61
- // Clicked outside the datepicker, hide it
62
- if ($(e.target).closest('.datepicker').length == 0) {
63
- that.hide();
64
- }
65
- });
66
-
67
- this.autoclose = false;
68
- if ('autoclose' in options) {
69
- this.autoclose = options.autoclose;
70
- } else if ('dateAutoclose' in this.element.data()) {
71
- this.autoclose = this.element.data('date-autoclose');
72
  }
73
 
74
- this.keyboardNavigation = true;
75
- if ('keyboardNavigation' in options) {
76
- this.keyboardNavigation = options.keyboardNavigation;
77
- } else if ('dateKeyboardNavigation' in this.element.data()) {
78
- this.keyboardNavigation = this.element.data('date-keyboard-navigation');
79
  }
80
 
81
- switch(options.startView || this.element.data('date-start-view')){
82
- case 2:
83
- case 'decade':
84
- this.viewMode = this.startViewMode = 2;
85
- break;
86
- case 1:
87
- case 'year':
88
- this.viewMode = this.startViewMode = 1;
89
- break;
90
- case 0:
91
- case 'month':
92
- default:
93
- this.viewMode = this.startViewMode = 0;
94
- break;
95
- }
96
 
97
- this.todayBtn = (options.todayBtn||this.element.data('date-today-btn')||false);
98
- this.todayHighlight = (options.todayHighlight||this.element.data('date-today-highlight')||false);
99
-
100
- this.weekStart = ((options.weekStart||this.element.data('date-weekstart')||dates[this.language].weekStart||0) % 7);
101
- this.weekEnd = ((this.weekStart + 6) % 7);
102
- this.startDate = -Infinity;
103
- this.endDate = Infinity;
104
- this.daysOfWeekDisabled = [];
105
- this.setStartDate(options.startDate||this.element.data('date-startdate'));
106
- this.setEndDate(options.endDate||this.element.data('date-enddate'));
107
- this.setDaysOfWeekDisabled(options.daysOfWeekDisabled||this.element.data('date-days-of-week-disabled'));
108
  this.fillDow();
109
  this.fillMonths();
 
 
 
110
  this.update();
111
  this.showMode();
 
 
 
 
112
  };
113
 
114
  Datepicker.prototype = {
115
  constructor: Datepicker,
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  _events: [],
118
- _attachEvents: function(){
119
- this._detachEvents();
120
- if (this.isInput) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  this._events = [
122
  [this.element, {
123
  focus: $.proxy(this.show, this),
124
- keyup: $.proxy(this.update, this),
 
 
 
125
  keydown: $.proxy(this.keydown, this)
126
  }]
127
  ];
128
  }
129
- else if (this.component && this.hasInput){
130
  this._events = [
131
  // For components that are not readonly, allow keyboard nav
132
  [this.element.find('input'), {
133
  focus: $.proxy(this.show, this),
134
- keyup: $.proxy(this.update, this),
 
 
 
135
  keydown: $.proxy(this.keydown, this)
136
  }],
137
  [this.component, {
@@ -139,6 +322,9 @@
139
  }]
140
  ];
141
  }
 
 
 
142
  else {
143
  this._events = [
144
  [this.element, {
@@ -146,246 +332,503 @@
146
  }]
147
  ];
148
  }
149
- for (var i=0, el, ev; i<this._events.length; i++){
150
- el = this._events[i][0];
151
- ev = this._events[i][1];
152
- el.on(ev);
153
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  },
155
  _detachEvents: function(){
156
- for (var i=0, el, ev; i<this._events.length; i++){
157
- el = this._events[i][0];
158
- ev = this._events[i][1];
159
- el.off(ev);
160
- }
161
- this._events = [];
162
  },
 
 
 
 
 
 
163
 
164
- show: function(e) {
165
- this.picker.show();
166
- this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
167
- this.update();
168
- this.place();
169
- $(window).on('resize', $.proxy(this.place, this));
170
- if (e ) {
171
- e.stopPropagation();
172
- e.preventDefault();
173
- }
174
  this.element.trigger({
175
- type: 'show',
176
- date: this.date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  });
178
  },
179
 
180
- hide: function(e){
181
- this.picker.hide();
182
- $(window).off('resize', this.place);
183
- this.viewMode = this.startViewMode;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  this.showMode();
185
- if (!this.isInput) {
186
- $(document).off('mousedown', this.hide);
187
- }
188
 
189
  if (
190
- this.forceParse &&
191
  (
192
  this.isInput && this.element.val() ||
193
  this.hasInput && this.element.find('input').val()
194
  )
195
  )
196
  this.setValue();
197
- this.element.trigger({
198
- type: 'hide',
199
- date: this.date
200
- });
201
  },
202
 
203
- remove: function() {
 
204
  this._detachEvents();
 
205
  this.picker.remove();
206
  delete this.element.data().datepicker;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  },
208
 
209
- getDate: function() {
210
- var d = this.getUTCDate();
211
- return new Date(d.getTime() + (d.getTimezoneOffset()*60000))
212
  },
213
 
214
- getUTCDate: function() {
215
- return this.date;
 
 
216
  },
217
 
218
- setDate: function(d) {
219
- this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset()*60000)));
220
  },
221
 
222
- setUTCDate: function(d) {
223
- this.date = d;
 
 
 
 
 
 
224
  this.setValue();
225
  },
226
 
227
- setValue: function() {
228
- var formatted = DPGlobal.formatDate(this.date, this.format, this.language);
229
- if (!this.isInput) {
 
 
 
 
 
 
 
 
 
 
230
  if (this.component){
231
- this.element.find('input').prop('value', formatted);
232
  }
233
- this.element.data('date', formatted);
234
- } else {
235
- this.element.prop('value', formatted);
236
  }
237
  },
238
 
 
 
 
 
 
 
 
 
 
 
239
  setStartDate: function(startDate){
240
- this.startDate = startDate||-Infinity;
241
- if (this.startDate !== -Infinity) {
242
- this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language);
243
- }
244
  this.update();
245
  this.updateNavArrows();
246
  },
247
 
248
  setEndDate: function(endDate){
249
- this.endDate = endDate||Infinity;
250
- if (this.endDate !== Infinity) {
251
- this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language);
252
- }
253
  this.update();
254
  this.updateNavArrows();
255
  },
256
 
257
  setDaysOfWeekDisabled: function(daysOfWeekDisabled){
258
- this.daysOfWeekDisabled = daysOfWeekDisabled||[];
259
- if (!$.isArray(this.daysOfWeekDisabled)) {
260
- this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
261
- }
262
- this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) {
263
- return parseInt(d, 10);
264
- });
265
  this.update();
266
  this.updateNavArrows();
267
  },
268
 
269
  place: function(){
270
- var zIndex = parseInt(this.element.parents().filter(function() {
271
- return $(this).css('z-index') != 'auto';
272
- }).first().css('z-index'))+10;
273
- var offset = this.component ? this.component.offset() : this.element.offset();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  this.picker.css({
275
- top: offset.top + this.height,
276
- left: offset.left,
277
  zIndex: zIndex
278
  });
279
  },
280
 
 
281
  update: function(){
282
- this.date = DPGlobal.parseDate(
283
- this.isInput ? this.element.prop('value') : this.element.data('date') || this.element.find('input').prop('value'),
284
- this.format, this.language
285
- );
286
- if (this.date < this.startDate) {
287
- this.viewDate = new Date(this.startDate);
288
- } else if (this.date > this.endDate) {
289
- this.viewDate = new Date(this.endDate);
290
- } else {
291
- this.viewDate = new Date(this.date);
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  this.fill();
294
  },
295
 
296
  fillDow: function(){
297
- var dowCnt = this.weekStart;
298
- var html = '<tr>';
299
- while (dowCnt < this.weekStart + 7) {
300
- html += '<th class="dow">'+dates[this.language].daysMin[(dowCnt++)%7]+'</th>';
 
 
 
 
 
301
  }
302
  html += '</tr>';
303
  this.picker.find('.datepicker-days thead').append(html);
304
  },
305
 
306
  fillMonths: function(){
307
- var html = '';
308
- var i = 0
309
- while (i < 12) {
310
- html += '<span class="month">'+dates[this.language].monthsShort[i++]+'</span>';
311
  }
312
  this.picker.find('.datepicker-months td').html(html);
313
  },
314
 
315
- fill: function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  var d = new Date(this.viewDate),
317
  year = d.getUTCFullYear(),
318
  month = d.getUTCMonth(),
319
- startYear = this.startDate !== -Infinity ? this.startDate.getUTCFullYear() : -Infinity,
320
- startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() : -Infinity,
321
- endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity,
322
- endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity,
323
- currentDate = this.date.valueOf(),
324
- today = new Date();
325
- this.picker.find('.datepicker-days thead th:eq(1)')
326
- .text(dates[this.language].months[month]+' '+year);
 
327
  this.picker.find('tfoot th.today')
328
- .text(dates[this.language].today)
329
- .toggle(this.todayBtn !== false);
 
 
 
330
  this.updateNavArrows();
331
  this.fillMonths();
332
- var prevMonth = UTCDate(year, month-1, 28,0,0,0,0),
333
  day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
334
  prevMonth.setUTCDate(day);
335
- prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7)%7);
336
  var nextMonth = new Date(prevMonth);
337
  nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
338
  nextMonth = nextMonth.valueOf();
339
  var html = [];
340
  var clsName;
341
- while(prevMonth.valueOf() < nextMonth) {
342
- if (prevMonth.getUTCDay() == this.weekStart) {
343
  html.push('<tr>');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  }
345
- clsName = '';
346
- if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {
347
- clsName += ' old';
348
- } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() > month)) {
349
- clsName += ' new';
350
- }
351
- // Compare internal UTC date with local today, not UTC today
352
- if (this.todayHighlight &&
353
- prevMonth.getUTCFullYear() == today.getFullYear() &&
354
- prevMonth.getUTCMonth() == today.getMonth() &&
355
- prevMonth.getUTCDate() == today.getDate()) {
356
- clsName += ' today';
357
- }
358
- if (prevMonth.valueOf() == currentDate) {
359
- clsName += ' button-primary';
360
- }
361
- if (prevMonth.valueOf() < this.startDate || prevMonth.valueOf() > this.endDate ||
362
- $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1) {
363
- clsName += ' disabled';
364
  }
365
- html.push('<td class="day'+clsName+'">'+prevMonth.getUTCDate() + '</td>');
366
- if (prevMonth.getUTCDay() == this.weekEnd) {
 
 
367
  html.push('</tr>');
368
  }
369
  prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
370
  }
371
  this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
372
- var currentYear = this.date.getUTCFullYear();
373
 
374
  var months = this.picker.find('.datepicker-months')
375
  .find('th:eq(1)')
376
  .text(year)
377
  .end()
378
- .find('span').removeClass('button-primary');
379
- if (currentYear == year) {
380
- months.eq(this.date.getUTCMonth()).addClass('button-primary');
381
- }
382
- if (year < startYear || year > endYear) {
 
 
 
383
  months.addClass('disabled');
384
  }
385
- if (year == startYear) {
386
  months.slice(0, startMonth).addClass('disabled');
387
  }
388
- if (year == endYear) {
389
  months.slice(endMonth+1).addClass('disabled');
390
  }
391
 
@@ -397,101 +840,139 @@
397
  .end()
398
  .find('td');
399
  year -= 1;
400
- for (var i = -1; i < 11; i++) {
401
- html += '<span class="year'+(i == -1 || i == 10 ? ' old' : '')+(currentYear == year ? ' button-primary' : '')+(year < startYear || year > endYear ? ' disabled' : '')+'">'+year+'</span>';
 
 
 
 
 
 
 
 
 
 
 
 
 
402
  year += 1;
403
  }
404
  yearCont.html(html);
405
  },
406
 
407
- updateNavArrows: function() {
 
 
 
408
  var d = new Date(this.viewDate),
409
  year = d.getUTCFullYear(),
410
  month = d.getUTCMonth();
411
- switch (this.viewMode) {
412
  case 0:
413
- if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear() && month <= this.startDate.getUTCMonth()) {
414
  this.picker.find('.prev').css({visibility: 'hidden'});
415
- } else {
 
416
  this.picker.find('.prev').css({visibility: 'visible'});
417
  }
418
- if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear() && month >= this.endDate.getUTCMonth()) {
419
  this.picker.find('.next').css({visibility: 'hidden'});
420
- } else {
 
421
  this.picker.find('.next').css({visibility: 'visible'});
422
  }
423
  break;
424
  case 1:
425
  case 2:
426
- if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()) {
427
  this.picker.find('.prev').css({visibility: 'hidden'});
428
- } else {
 
429
  this.picker.find('.prev').css({visibility: 'visible'});
430
  }
431
- if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()) {
432
  this.picker.find('.next').css({visibility: 'hidden'});
433
- } else {
 
434
  this.picker.find('.next').css({visibility: 'visible'});
435
  }
436
  break;
437
  }
438
  },
439
 
440
- click: function(e) {
441
- e.stopPropagation();
442
  e.preventDefault();
443
- var target = $(e.target).closest('span, td, th');
444
- if (target.length == 1) {
445
- switch(target[0].nodeName.toLowerCase()) {
 
446
  case 'th':
447
- switch(target[0].className) {
448
- case 'switch':
449
  this.showMode(1);
450
  break;
451
  case 'prev':
452
  case 'next':
453
- var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1);
454
- switch(this.viewMode){
455
  case 0:
456
  this.viewDate = this.moveMonth(this.viewDate, dir);
 
457
  break;
458
  case 1:
459
  case 2:
460
  this.viewDate = this.moveYear(this.viewDate, dir);
 
 
461
  break;
462
  }
463
  this.fill();
464
  break;
465
  case 'today':
466
  var date = new Date();
467
- date.setUTCHours(0);
468
- date.setUTCMinutes(0);
469
- date.setUTCSeconds(0);
470
- date.setUTCMilliseconds(0);
471
 
472
  this.showMode(-2);
473
- var which = this.todayBtn == 'linked' ? null : 'view';
474
  this._setDate(date, which);
475
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
476
  }
477
  break;
478
  case 'span':
479
- if (!target.is('.disabled')) {
480
  this.viewDate.setUTCDate(1);
481
- if (target.is('.month')) {
482
- var month = target.parent().find('span').index(target);
 
 
483
  this.viewDate.setUTCMonth(month);
484
- this.element.trigger({
485
- type: 'changeMonth',
486
- date: this.viewDate
487
- });
488
- } else {
489
- var year = parseInt(target.text(), 10)||0;
 
 
 
490
  this.viewDate.setUTCFullYear(year);
491
- this.element.trigger({
492
- type: 'changeYear',
493
- date: this.viewDate
494
- });
495
  }
496
  this.showMode(-1);
497
  this.fill();
@@ -499,86 +980,118 @@
499
  break;
500
  case 'td':
501
  if (target.is('.day') && !target.is('.disabled')){
502
- var day = parseInt(target.text(), 10)||1;
503
- var year = this.viewDate.getUTCFullYear(),
504
- month = this.viewDate.getUTCMonth();
505
- if (target.is('.old')) {
506
- if (month == 0) {
507
  month = 11;
508
  year -= 1;
509
- } else {
 
510
  month -= 1;
511
  }
512
- } else if (target.is('.new')) {
513
- if (month == 11) {
 
514
  month = 0;
515
  year += 1;
516
- } else {
 
517
  month += 1;
518
  }
519
  }
520
- this._setDate(UTCDate(year, month, day,0,0,0,0));
521
  }
522
  break;
523
  }
524
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  },
526
 
527
  _setDate: function(date, which){
528
- if (!which || which == 'date')
529
- this.date = date;
530
- if (!which || which == 'view')
531
- this.viewDate = date;
 
532
  this.fill();
533
  this.setValue();
534
- this.element.trigger({
535
- type: 'changeDate',
536
- date: this.date
537
- });
538
  var element;
539
- if (this.isInput) {
540
  element = this.element;
541
- } else if (this.component){
 
542
  element = this.element.find('input');
543
  }
544
- if (element) {
545
  element.change();
546
- if (this.autoclose && (!which || which == 'date')) {
547
- this.hide();
548
- }
549
  }
550
  },
551
 
552
  moveMonth: function(date, dir){
553
- if (!dir) return date;
 
 
 
554
  var new_date = new Date(date.valueOf()),
555
  day = new_date.getUTCDate(),
556
  month = new_date.getUTCMonth(),
557
  mag = Math.abs(dir),
558
  new_month, test;
559
  dir = dir > 0 ? 1 : -1;
560
- if (mag == 1){
561
- test = dir == -1
562
  // If going back one month, make sure month is not current month
563
  // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
564
- ? function(){ return new_date.getUTCMonth() == month; }
 
 
565
  // If going forward one month, make sure month is as expected
566
  // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
567
- : function(){ return new_date.getUTCMonth() != new_month; };
 
 
568
  new_month = month + dir;
569
  new_date.setUTCMonth(new_month);
570
  // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
571
  if (new_month < 0 || new_month > 11)
572
  new_month = (new_month + 12) % 12;
573
- } else {
 
574
  // For magnitudes >1, move one month at a time...
575
- for (var i=0; i<mag; i++)
576
  // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
577
  new_date = this.moveMonth(new_date, dir);
578
  // ...then reset the day, keeping it in the new month
579
  new_month = new_date.getUTCMonth();
580
  new_date.setUTCDate(day);
581
- test = function(){ return new_month != new_date.getUTCMonth(); };
 
 
582
  }
583
  // Common date-resetting loop -- if date is beyond end of month, make it
584
  // end of month
@@ -594,125 +1107,314 @@
594
  },
595
 
596
  dateWithinRange: function(date){
597
- return date >= this.startDate && date <= this.endDate;
598
  },
599
 
600
  keydown: function(e){
601
  if (this.picker.is(':not(:visible)')){
602
- if (e.keyCode == 27) // allow escape to hide and re-show picker
603
  this.show();
604
  return;
605
  }
606
  var dateChanged = false,
607
- dir, day, month,
608
- newDate, newViewDate;
609
- switch(e.keyCode){
610
  case 27: // escape
611
- this.hide();
 
 
 
 
 
 
612
  e.preventDefault();
613
  break;
614
  case 37: // left
615
  case 39: // right
616
- if (!this.keyboardNavigation) break;
617
- dir = e.keyCode == 37 ? -1 : 1;
 
618
  if (e.ctrlKey){
619
- newDate = this.moveYear(this.date, dir);
620
- newViewDate = this.moveYear(this.viewDate, dir);
621
- } else if (e.shiftKey){
622
- newDate = this.moveMonth(this.date, dir);
623
- newViewDate = this.moveMonth(this.viewDate, dir);
624
- } else {
625
- newDate = new Date(this.date);
626
- newDate.setUTCDate(this.date.getUTCDate() + dir);
627
- newViewDate = new Date(this.viewDate);
628
- newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir);
 
 
 
 
629
  }
630
  if (this.dateWithinRange(newDate)){
631
- this.date = newDate;
632
- this.viewDate = newViewDate;
633
  this.setValue();
634
- this.update();
635
  e.preventDefault();
636
- dateChanged = true;
637
  }
638
  break;
639
  case 38: // up
640
  case 40: // down
641
- if (!this.keyboardNavigation) break;
642
- dir = e.keyCode == 38 ? -1 : 1;
 
643
  if (e.ctrlKey){
644
- newDate = this.moveYear(this.date, dir);
645
- newViewDate = this.moveYear(this.viewDate, dir);
646
- } else if (e.shiftKey){
647
- newDate = this.moveMonth(this.date, dir);
648
- newViewDate = this.moveMonth(this.viewDate, dir);
649
- } else {
650
- newDate = new Date(this.date);
651
- newDate.setUTCDate(this.date.getUTCDate() + dir * 7);
652
- newViewDate = new Date(this.viewDate);
653
- newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir * 7);
 
 
 
 
654
  }
655
  if (this.dateWithinRange(newDate)){
656
- this.date = newDate;
657
- this.viewDate = newViewDate;
658
  this.setValue();
659
- this.update();
660
  e.preventDefault();
661
- dateChanged = true;
662
  }
663
  break;
 
 
 
 
664
  case 13: // enter
665
- this.hide();
666
- e.preventDefault();
 
 
 
 
 
 
 
 
 
 
667
  break;
668
  case 9: // tab
 
 
 
669
  this.hide();
670
  break;
671
  }
672
  if (dateChanged){
673
- this.element.trigger({
674
- type: 'changeDate',
675
- date: this.date
676
- });
677
  var element;
678
- if (this.isInput) {
679
  element = this.element;
680
- } else if (this.component){
 
681
  element = this.element.find('input');
682
  }
683
- if (element) {
684
  element.change();
685
  }
686
  }
687
  },
688
 
689
- showMode: function(dir) {
690
- if (dir) {
691
- this.viewMode = Math.max(0, Math.min(2, this.viewMode + dir));
692
  }
693
- this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
 
 
 
 
694
  this.updateNavArrows();
695
  }
696
  };
697
 
698
- $.fn.datepicker = function ( option ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
699
  var args = Array.apply(null, arguments);
700
  args.shift();
701
- return this.each(function () {
 
702
  var $this = $(this),
703
  data = $this.data('datepicker'),
704
- options = typeof option == 'object' && option;
705
- if (!data) {
706
- $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
  }
708
- if (typeof option == 'string' && typeof data[option] == 'function') {
709
- data[option].apply(data, args);
 
 
710
  }
711
  });
 
 
 
 
712
  };
713
 
714
- $.fn.datepicker.defaults = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  };
 
 
 
 
 
716
  $.fn.datepicker.Constructor = Datepicker;
717
  var dates = $.fn.datepicker.dates = {
718
  en: {
@@ -721,9 +1423,10 @@
721
  daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
722
  months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
723
  monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
724
- today: "Today"
 
725
  }
726
- }
727
 
728
  var DPGlobal = {
729
  modes: [
@@ -742,35 +1445,40 @@
742
  navFnc: 'FullYear',
743
  navStep: 10
744
  }],
745
- isLeapYear: function (year) {
746
- return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
747
  },
748
- getDaysInMonth: function (year, month) {
749
- return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
750
  },
751
- validParts: /dd?|mm?|MM?|yy(?:yy)?/g,
752
- nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\r]+/g,
753
  parseFormat: function(format){
754
  // IE treats \0 as a string end in inputs (truncating the value),
755
  // so it's a bad format delimiter, anyway
756
  var separators = format.replace(this.validParts, '\0').split('\0'),
757
  parts = format.match(this.validParts);
758
- if (!separators || !separators.length || !parts || parts.length == 0){
759
  throw new Error("Invalid date format.");
760
  }
761
  return {separators: separators, parts: parts};
762
  },
763
- parseDate: function(date, format, language) {
764
- if (date instanceof Date) return date;
765
- if (/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(date)) {
766
- var part_re = /([-+]\d+)([dmwy])/,
767
- parts = date.match(/([-+]\d+)([dmwy])/g),
768
- part, dir;
 
 
 
 
 
769
  date = new Date();
770
- for (var i=0; i<parts.length; i++) {
771
  part = part_re.exec(parts[i]);
772
  dir = parseInt(part[1]);
773
- switch(part[2]){
774
  case 'd':
775
  date.setUTCDate(date.getUTCDate() + dir);
776
  break;
@@ -787,65 +1495,90 @@
787
  }
788
  return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
789
  }
790
- var parts = date && date.match(this.nonpunctuation) || [],
791
- date = new Date(),
792
- parsed = {},
793
  setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
794
  setters_map = {
795
- yyyy: function(d,v){ return d.setUTCFullYear(v); },
796
- yy: function(d,v){ return d.setUTCFullYear(2000+v); },
 
 
 
 
797
  m: function(d,v){
 
 
798
  v -= 1;
799
- while (v<0) v += 12;
800
  v %= 12;
801
  d.setUTCMonth(v);
802
- while (d.getUTCMonth() != v)
803
  d.setUTCDate(d.getUTCDate()-1);
804
  return d;
805
  },
806
- d: function(d,v){ return d.setUTCDate(v); }
 
 
807
  },
808
- val, filtered, part;
809
  setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
810
  setters_map['dd'] = setters_map['d'];
811
  date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
812
- if (parts.length == format.parts.length) {
813
- for (var i=0, cnt = format.parts.length; i < cnt; i++) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
814
  val = parseInt(parts[i], 10);
815
- part = format.parts[i];
816
- if (isNaN(val)) {
817
- switch(part) {
818
  case 'MM':
819
- filtered = $(dates[language].months).filter(function(){
820
- var m = this.slice(0, parts[i].length),
821
- p = parts[i].slice(0, m.length);
822
- return m == p;
823
- });
824
  val = $.inArray(filtered[0], dates[language].months) + 1;
825
  break;
826
  case 'M':
827
- filtered = $(dates[language].monthsShort).filter(function(){
828
- var m = this.slice(0, parts[i].length),
829
- p = parts[i].slice(0, m.length);
830
- return m == p;
831
- });
832
  val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
833
  break;
834
  }
835
  }
836
  parsed[part] = val;
837
  }
838
- for (var i=0, s; i<setters_order.length; i++){
 
839
  s = setters_order[i];
840
- if (s in parsed && !isNaN(parsed[s]))
841
- setters_map[s](date, parsed[s])
 
 
 
 
842
  }
843
  }
844
  return date;
845
  },
846
  formatDate: function(date, format, language){
 
 
 
 
847
  var val = {
848
  d: date.getUTCDate(),
 
 
849
  m: date.getUTCMonth() + 1,
850
  M: dates[language].monthsShort[date.getUTCMonth()],
851
  MM: dates[language].months[date.getUTCMonth()],
@@ -854,26 +1587,33 @@
854
  };
855
  val.dd = (val.d < 10 ? '0' : '') + val.d;
856
  val.mm = (val.m < 10 ? '0' : '') + val.m;
857
- var date = [],
858
- seps = $.extend([], format.separators);
859
- for (var i=0, cnt = format.parts.length; i < cnt; i++) {
860
  if (seps.length)
861
- date.push(seps.shift())
862
  date.push(val[format.parts[i]]);
863
  }
864
  return date.join('');
865
  },
866
  headTemplate: '<thead>'+
867
  '<tr>'+
868
- '<th class="prev"><i class="icon-arrow-left"/></th>'+
869
- '<th colspan="5" class="switch"></th>'+
870
- '<th class="next"><i class="icon-arrow-right"/></th>'+
871
  '</tr>'+
872
  '</thead>',
873
  contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
874
- footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'
 
 
 
 
 
 
 
875
  };
876
- DPGlobal.template = '<div class="datepicker dropdown-menu">'+
877
  '<div class="datepicker-days">'+
878
  '<table class=" table-condensed">'+
879
  DPGlobal.headTemplate+
@@ -896,26 +1636,36 @@
896
  '</table>'+
897
  '</div>'+
898
  '</div>';
899
- }( window.jQuery );
900
-
901
-
902
- jQuery(function($){
903
-
904
- $('body').on('mouseover', function(){
905
-
906
- var picker = $('.is-datepicker').datepicker({}).on('changeDate', function(ev) {
907
- picker.hide();
908
- }).data('datepicker');
909
-
910
- });
911
-
912
- });
913
-
914
 
 
915
 
916
 
 
 
917
 
 
 
 
 
918
 
919
 
 
 
920
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
921
 
 
1
  /* =========================================================
2
  * bootstrap-datepicker.js
3
+ * Repo: https://github.com/eternicode/bootstrap-datepicker/
4
+ * Demo: http://eternicode.github.io/bootstrap-datepicker/
5
+ * Docs: http://bootstrap-datepicker.readthedocs.org/
6
+ * Forked from http://www.eyecon.ro/bootstrap-datepicker
7
  * =========================================================
8
+ * Started by Stefan Petre; improvements by Andrew Rowls + contributors
 
9
  *
10
  * Licensed under the Apache License, Version 2.0 (the "License");
11
  * you may not use this file except in compliance with the License.
20
  * limitations under the License.
21
  * ========================================================= */
22
 
23
+ (function($, undefined){
24
+
25
+ var $window = $(window);
26
 
27
  function UTCDate(){
28
  return new Date(Date.UTC.apply(Date, arguments));
29
  }
30
  function UTCToday(){
31
  var today = new Date();
32
+ return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
33
+ }
34
+ function alias(method){
35
+ return function(){
36
+ return this[method].apply(this, arguments);
37
+ };
38
  }
39
 
40
+ var DateArray = (function(){
41
+ var extras = {
42
+ get: function(i){
43
+ return this.slice(i)[0];
44
+ },
45
+ contains: function(d){
46
+ // Array.indexOf is not cross-browser;
47
+ // $.inArray doesn't work with Dates
48
+ var val = d && d.valueOf();
49
+ for (var i=0, l=this.length; i < l; i++)
50
+ if (this[i].valueOf() === val)
51
+ return i;
52
+ return -1;
53
+ },
54
+ remove: function(i){
55
+ this.splice(i,1);
56
+ },
57
+ replace: function(new_array){
58
+ if (!new_array)
59
+ return;
60
+ if (!$.isArray(new_array))
61
+ new_array = [new_array];
62
+ this.clear();
63
+ this.push.apply(this, new_array);
64
+ },
65
+ clear: function(){
66
+ this.splice(0);
67
+ },
68
+ copy: function(){
69
+ var a = new DateArray();
70
+ a.replace(this);
71
+ return a;
72
+ }
73
+ };
74
+
75
+ return function(){
76
+ var a = [];
77
+ a.push.apply(a, arguments);
78
+ $.extend(a, extras);
79
+ return a;
80
+ };
81
+ })();
82
+
83
+
84
  // Picker object
85
 
86
+ var Datepicker = function(element, options){
87
+ this.dates = new DateArray();
88
+ this.viewDate = UTCToday();
89
+ this.focusDate = null;
90
+
91
+ this._process_options(options);
92
 
93
  this.element = $(element);
94
+ this.isInline = false;
 
 
 
 
 
 
 
95
  this.isInput = this.element.is('input');
96
+ this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
97
  this.hasInput = this.component && this.element.find('input').length;
98
+ if (this.component && this.component.length === 0)
99
  this.component = false;
100
 
101
+ this.picker = $(DPGlobal.template);
102
+ this._buildEvents();
103
  this._attachEvents();
104
 
105
+ if (this.isInline){
106
+ this.picker.addClass('datepicker-inline').appendTo(this.element);
 
 
 
107
  }
108
+ else {
109
+ this.picker.addClass('datepicker-dropdown dropdown-menu');
 
 
 
 
 
 
 
 
 
 
 
110
  }
111
 
112
+ if (this.o.rtl){
113
+ this.picker.addClass('datepicker-rtl');
 
 
 
114
  }
115
 
116
+ this.viewMode = this.o.startView;
117
+
118
+ if (this.o.calendarWeeks)
119
+ this.picker.find('tfoot th.today')
120
+ .attr('colspan', function(i, val){
121
+ return parseInt(val) + 1;
122
+ });
123
+
124
+ this._allow_update = false;
125
+
126
+ this.setStartDate(this._o.startDate);
127
+ this.setEndDate(this._o.endDate);
128
+ this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
 
 
129
 
 
 
 
 
 
 
 
 
 
 
 
130
  this.fillDow();
131
  this.fillMonths();
132
+
133
+ this._allow_update = true;
134
+
135
  this.update();
136
  this.showMode();
137
+
138
+ if (this.isInline){
139
+ this.show();
140
+ }
141
  };
142
 
143
  Datepicker.prototype = {
144
  constructor: Datepicker,
145
 
146
+ _process_options: function(opts){
147
+ // Store raw options for reference
148
+ this._o = $.extend({}, this._o, opts);
149
+ // Processed options
150
+ var o = this.o = $.extend({}, this._o);
151
+
152
+ // Check if "de-DE" style date is available, if not language should
153
+ // fallback to 2 letter code eg "de"
154
+ var lang = o.language;
155
+ if (!dates[lang]){
156
+ lang = lang.split('-')[0];
157
+ if (!dates[lang])
158
+ lang = defaults.language;
159
+ }
160
+ o.language = lang;
161
+
162
+ switch (o.startView){
163
+ case 2:
164
+ case 'decade':
165
+ o.startView = 2;
166
+ break;
167
+ case 1:
168
+ case 'year':
169
+ o.startView = 1;
170
+ break;
171
+ default:
172
+ o.startView = 0;
173
+ }
174
+
175
+ switch (o.minViewMode){
176
+ case 1:
177
+ case 'months':
178
+ o.minViewMode = 1;
179
+ break;
180
+ case 2:
181
+ case 'years':
182
+ o.minViewMode = 2;
183
+ break;
184
+ default:
185
+ o.minViewMode = 0;
186
+ }
187
+
188
+ o.startView = Math.max(o.startView, o.minViewMode);
189
+
190
+ // true, false, or Number > 0
191
+ if (o.multidate !== true){
192
+ o.multidate = Number(o.multidate) || false;
193
+ if (o.multidate !== false)
194
+ o.multidate = Math.max(0, o.multidate);
195
+ else
196
+ o.multidate = 1;
197
+ }
198
+ o.multidateSeparator = String(o.multidateSeparator);
199
+
200
+ o.weekStart %= 7;
201
+ o.weekEnd = ((o.weekStart + 6) % 7);
202
+
203
+ var format = DPGlobal.parseFormat(o.format);
204
+ if (o.startDate !== -Infinity){
205
+ if (!!o.startDate){
206
+ if (o.startDate instanceof Date)
207
+ o.startDate = this._local_to_utc(this._zero_time(o.startDate));
208
+ else
209
+ o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
210
+ }
211
+ else {
212
+ o.startDate = -Infinity;
213
+ }
214
+ }
215
+ if (o.endDate !== Infinity){
216
+ if (!!o.endDate){
217
+ if (o.endDate instanceof Date)
218
+ o.endDate = this._local_to_utc(this._zero_time(o.endDate));
219
+ else
220
+ o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
221
+ }
222
+ else {
223
+ o.endDate = Infinity;
224
+ }
225
+ }
226
+
227
+ o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
228
+ if (!$.isArray(o.daysOfWeekDisabled))
229
+ o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
230
+ o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
231
+ return parseInt(d, 10);
232
+ });
233
+
234
+ var plc = String(o.orientation).toLowerCase().split(/\s+/g),
235
+ _plc = o.orientation.toLowerCase();
236
+ plc = $.grep(plc, function(word){
237
+ return (/^auto|left|right|top|bottom$/).test(word);
238
+ });
239
+ o.orientation = {x: 'auto', y: 'auto'};
240
+ if (!_plc || _plc === 'auto')
241
+ ; // no action
242
+ else if (plc.length === 1){
243
+ switch (plc[0]){
244
+ case 'top':
245
+ case 'bottom':
246
+ o.orientation.y = plc[0];
247
+ break;
248
+ case 'left':
249
+ case 'right':
250
+ o.orientation.x = plc[0];
251
+ break;
252
+ }
253
+ }
254
+ else {
255
+ _plc = $.grep(plc, function(word){
256
+ return (/^left|right$/).test(word);
257
+ });
258
+ o.orientation.x = _plc[0] || 'auto';
259
+
260
+ _plc = $.grep(plc, function(word){
261
+ return (/^top|bottom$/).test(word);
262
+ });
263
+ o.orientation.y = _plc[0] || 'auto';
264
+ }
265
+ },
266
  _events: [],
267
+ _secondaryEvents: [],
268
+ _applyEvents: function(evs){
269
+ for (var i=0, el, ch, ev; i < evs.length; i++){
270
+ el = evs[i][0];
271
+ if (evs[i].length === 2){
272
+ ch = undefined;
273
+ ev = evs[i][1];
274
+ }
275
+ else if (evs[i].length === 3){
276
+ ch = evs[i][1];
277
+ ev = evs[i][2];
278
+ }
279
+ el.on(ev, ch);
280
+ }
281
+ },
282
+ _unapplyEvents: function(evs){
283
+ for (var i=0, el, ev, ch; i < evs.length; i++){
284
+ el = evs[i][0];
285
+ if (evs[i].length === 2){
286
+ ch = undefined;
287
+ ev = evs[i][1];
288
+ }
289
+ else if (evs[i].length === 3){
290
+ ch = evs[i][1];
291
+ ev = evs[i][2];
292
+ }
293
+ el.off(ev, ch);
294
+ }
295
+ },
296
+ _buildEvents: function(){
297
+ if (this.isInput){ // single input
298
  this._events = [
299
  [this.element, {
300
  focus: $.proxy(this.show, this),
301
+ keyup: $.proxy(function(e){
302
+ if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)
303
+ this.update();
304
+ }, this),
305
  keydown: $.proxy(this.keydown, this)
306
  }]
307
  ];
308
  }
309
+ else if (this.component && this.hasInput){ // component: input + button
310
  this._events = [
311
  // For components that are not readonly, allow keyboard nav
312
  [this.element.find('input'), {
313
  focus: $.proxy(this.show, this),
314
+ keyup: $.proxy(function(e){
315
+ if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)
316
+ this.update();
317
+ }, this),
318
  keydown: $.proxy(this.keydown, this)
319
  }],
320
  [this.component, {
322
  }]
323
  ];
324
  }
325
+ else if (this.element.is('div')){ // inline datepicker
326
+ this.isInline = true;
327
+ }
328
  else {
329
  this._events = [
330
  [this.element, {
332
  }]
333
  ];
334
  }
335
+ this._events.push(
336
+ // Component: listen for blur on element descendants
337
+ [this.element, '*', {
338
+ blur: $.proxy(function(e){
339
+ this._focused_from = e.target;
340
+ }, this)
341
+ }],
342
+ // Input: listen for blur on element
343
+ [this.element, {
344
+ blur: $.proxy(function(e){
345
+ this._focused_from = e.target;
346
+ }, this)
347
+ }]
348
+ );
349
+
350
+ this._secondaryEvents = [
351
+ [this.picker, {
352
+ click: $.proxy(this.click, this)
353
+ }],
354
+ [$(window), {
355
+ resize: $.proxy(this.place, this)
356
+ }],
357
+ [$(document), {
358
+ 'mousedown touchstart': $.proxy(function(e){
359
+ // Clicked outside the datepicker, hide it
360
+ if (!(
361
+ this.element.is(e.target) ||
362
+ this.element.find(e.target).length ||
363
+ this.picker.is(e.target) ||
364
+ this.picker.find(e.target).length
365
+ )){
366
+ this.hide();
367
+ }
368
+ }, this)
369
+ }]
370
+ ];
371
+ },
372
+ _attachEvents: function(){
373
+ this._detachEvents();
374
+ this._applyEvents(this._events);
375
  },
376
  _detachEvents: function(){
377
+ this._unapplyEvents(this._events);
378
+ },
379
+ _attachSecondaryEvents: function(){
380
+ this._detachSecondaryEvents();
381
+ this._applyEvents(this._secondaryEvents);
 
382
  },
383
+ _detachSecondaryEvents: function(){
384
+ this._unapplyEvents(this._secondaryEvents);
385
+ },
386
+ _trigger: function(event, altdate){
387
+ var date = altdate || this.dates.get(-1),
388
+ local_date = this._utc_to_local(date);
389
 
 
 
 
 
 
 
 
 
 
 
390
  this.element.trigger({
391
+ type: event,
392
+ date: local_date,
393
+ dates: $.map(this.dates, this._utc_to_local),
394
+ format: $.proxy(function(ix, format){
395
+ if (arguments.length === 0){
396
+ ix = this.dates.length - 1;
397
+ format = this.o.format;
398
+ }
399
+ else if (typeof ix === 'string'){
400
+ format = ix;
401
+ ix = this.dates.length - 1;
402
+ }
403
+ format = format || this.o.format;
404
+ var date = this.dates.get(ix);
405
+ return DPGlobal.formatDate(date, format, this.o.language);
406
+ }, this)
407
  });
408
  },
409
 
410
+ show: function(){
411
+ if (!this.isInline)
412
+ this.picker.appendTo('body');
413
+ this.picker.show();
414
+ this.place();
415
+ this._attachSecondaryEvents();
416
+ this._trigger('show');
417
+ },
418
+
419
+ hide: function(){
420
+ if (this.isInline)
421
+ return;
422
+ if (!this.picker.is(':visible'))
423
+ return;
424
+ this.focusDate = null;
425
+ this.picker.hide().detach();
426
+ this._detachSecondaryEvents();
427
+ this.viewMode = this.o.startView;
428
  this.showMode();
 
 
 
429
 
430
  if (
431
+ this.o.forceParse &&
432
  (
433
  this.isInput && this.element.val() ||
434
  this.hasInput && this.element.find('input').val()
435
  )
436
  )
437
  this.setValue();
438
+ this._trigger('hide');
 
 
 
439
  },
440
 
441
+ remove: function(){
442
+ this.hide();
443
  this._detachEvents();
444
+ this._detachSecondaryEvents();
445
  this.picker.remove();
446
  delete this.element.data().datepicker;
447
+ if (!this.isInput){
448
+ delete this.element.data().date;
449
+ }
450
+ },
451
+
452
+ _utc_to_local: function(utc){
453
+ return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
454
+ },
455
+ _local_to_utc: function(local){
456
+ return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
457
+ },
458
+ _zero_time: function(local){
459
+ return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
460
+ },
461
+ _zero_utc_time: function(utc){
462
+ return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
463
  },
464
 
465
+ getDates: function(){
466
+ return $.map(this.dates, this._utc_to_local);
 
467
  },
468
 
469
+ getUTCDates: function(){
470
+ return $.map(this.dates, function(d){
471
+ return new Date(d);
472
+ });
473
  },
474
 
475
+ getDate: function(){
476
+ return this._utc_to_local(this.getUTCDate());
477
  },
478
 
479
+ getUTCDate: function(){
480
+ return new Date(this.dates.get(-1));
481
+ },
482
+
483
+ setDates: function(){
484
+ var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
485
+ this.update.apply(this, args);
486
+ this._trigger('changeDate');
487
  this.setValue();
488
  },
489
 
490
+ setUTCDates: function(){
491
+ var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
492
+ this.update.apply(this, $.map(args, this._utc_to_local));
493
+ this._trigger('changeDate');
494
+ this.setValue();
495
+ },
496
+
497
+ setDate: alias('setDates'),
498
+ setUTCDate: alias('setUTCDates'),
499
+
500
+ setValue: function(){
501
+ var formatted = this.getFormattedDate();
502
+ if (!this.isInput){
503
  if (this.component){
504
+ this.element.find('input').val(formatted).change();
505
  }
506
+ }
507
+ else {
508
+ this.element.val(formatted).change();
509
  }
510
  },
511
 
512
+ getFormattedDate: function(format){
513
+ if (format === undefined)
514
+ format = this.o.format;
515
+
516
+ var lang = this.o.language;
517
+ return $.map(this.dates, function(d){
518
+ return DPGlobal.formatDate(d, format, lang);
519
+ }).join(this.o.multidateSeparator);
520
+ },
521
+
522
  setStartDate: function(startDate){
523
+ this._process_options({startDate: startDate});
 
 
 
524
  this.update();
525
  this.updateNavArrows();
526
  },
527
 
528
  setEndDate: function(endDate){
529
+ this._process_options({endDate: endDate});
 
 
 
530
  this.update();
531
  this.updateNavArrows();
532
  },
533
 
534
  setDaysOfWeekDisabled: function(daysOfWeekDisabled){
535
+ this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
 
 
 
 
 
 
536
  this.update();
537
  this.updateNavArrows();
538
  },
539
 
540
  place: function(){
541
+ if (this.isInline)
542
+ return;
543
+ var calendarWidth = this.picker.outerWidth(),
544
+ calendarHeight = this.picker.outerHeight(),
545
+ visualPadding = 10,
546
+ windowWidth = $window.width(),
547
+ windowHeight = $window.height(),
548
+ scrollTop = $window.scrollTop();
549
+
550
+ var zIndex = parseInt(this.element.parents().filter(function(){
551
+ return $(this).css('z-index') !== 'auto';
552
+ }).first().css('z-index'))+10;
553
+ var offset = this.component ? this.component.parent().offset() : this.element.offset();
554
+ var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
555
+ var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
556
+ var left = offset.left,
557
+ top = offset.top;
558
+
559
+ this.picker.removeClass(
560
+ 'datepicker-orient-top datepicker-orient-bottom '+
561
+ 'datepicker-orient-right datepicker-orient-left'
562
+ );
563
+
564
+ if (this.o.orientation.x !== 'auto'){
565
+ this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
566
+ if (this.o.orientation.x === 'right')
567
+ left -= calendarWidth - width;
568
+ }
569
+ // auto x orientation is best-placement: if it crosses a window
570
+ // edge, fudge it sideways
571
+ else {
572
+ // Default to left
573
+ this.picker.addClass('datepicker-orient-left');
574
+ if (offset.left < 0)
575
+ left -= offset.left - visualPadding;
576
+ else if (offset.left + calendarWidth > windowWidth)
577
+ left = windowWidth - calendarWidth - visualPadding;
578
+ }
579
+
580
+ // auto y orientation is best-situation: top or bottom, no fudging,
581
+ // decision based on which shows more of the calendar
582
+ var yorient = this.o.orientation.y,
583
+ top_overflow, bottom_overflow;
584
+ if (yorient === 'auto'){
585
+ top_overflow = -scrollTop + offset.top - calendarHeight;
586
+ bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight);
587
+ if (Math.max(top_overflow, bottom_overflow) === bottom_overflow)
588
+ yorient = 'top';
589
+ else
590
+ yorient = 'bottom';
591
+ }
592
+ this.picker.addClass('datepicker-orient-' + yorient);
593
+ if (yorient === 'top')
594
+ top += height;
595
+ else
596
+ top -= calendarHeight + parseInt(this.picker.css('padding-top'));
597
+
598
  this.picker.css({
599
+ top: top,
600
+ left: left,
601
  zIndex: zIndex
602
  });
603
  },
604
 
605
+ _allow_update: true,
606
  update: function(){
607
+ if (!this._allow_update)
608
+ return;
609
+
610
+ var oldDates = this.dates.copy(),
611
+ dates = [],
612
+ fromArgs = false;
613
+ if (arguments.length){
614
+ $.each(arguments, $.proxy(function(i, date){
615
+ if (date instanceof Date)
616
+ date = this._local_to_utc(date);
617
+ dates.push(date);
618
+ }, this));
619
+ fromArgs = true;
620
+ }
621
+ else {
622
+ dates = this.isInput
623
+ ? this.element.val()
624
+ : this.element.data('date') || this.element.find('input').val();
625
+ if (dates && this.o.multidate)
626
+ dates = dates.split(this.o.multidateSeparator);
627
+ else
628
+ dates = [dates];
629
+ delete this.element.data().date;
630
  }
631
+
632
+ dates = $.map(dates, $.proxy(function(date){
633
+ return DPGlobal.parseDate(date, this.o.format, this.o.language);
634
+ }, this));
635
+ dates = $.grep(dates, $.proxy(function(date){
636
+ return (
637
+ date < this.o.startDate ||
638
+ date > this.o.endDate ||
639
+ !date
640
+ );
641
+ }, this), true);
642
+ this.dates.replace(dates);
643
+
644
+ if (this.dates.length)
645
+ this.viewDate = new Date(this.dates.get(-1));
646
+ else if (this.viewDate < this.o.startDate)
647
+ this.viewDate = new Date(this.o.startDate);
648
+ else if (this.viewDate > this.o.endDate)
649
+ this.viewDate = new Date(this.o.endDate);
650
+
651
+ if (fromArgs){
652
+ // setting date by clicking
653
+ this.setValue();
654
+ }
655
+ else if (dates.length){
656
+ // setting date by typing
657
+ if (String(oldDates) !== String(this.dates))
658
+ this._trigger('changeDate');
659
+ }
660
+ if (!this.dates.length && oldDates.length)
661
+ this._trigger('clearDate');
662
+
663
  this.fill();
664
  },
665
 
666
  fillDow: function(){
667
+ var dowCnt = this.o.weekStart,
668
+ html = '<tr>';
669
+ if (this.o.calendarWeeks){
670
+ var cell = '<th class="cw">&nbsp;</th>';
671
+ html += cell;
672
+ this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
673
+ }
674
+ while (dowCnt < this.o.weekStart + 7){
675
+ html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
676
  }
677
  html += '</tr>';
678
  this.picker.find('.datepicker-days thead').append(html);
679
  },
680
 
681
  fillMonths: function(){
682
+ var html = '',
683
+ i = 0;
684
+ while (i < 12){
685
+ html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>';
686
  }
687
  this.picker.find('.datepicker-months td').html(html);
688
  },
689
 
690
+ setRange: function(range){
691
+ if (!range || !range.length)
692
+ delete this.range;
693
+ else
694
+ this.range = $.map(range, function(d){
695
+ return d.valueOf();
696
+ });
697
+ this.fill();
698
+ },
699
+
700
+ getClassNames: function(date){
701
+ var cls = [],
702
+ year = this.viewDate.getUTCFullYear(),
703
+ month = this.viewDate.getUTCMonth(),
704
+ today = new Date();
705
+ if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
706
+ cls.push('old');
707
+ }
708
+ else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
709
+ cls.push('new');
710
+ }
711
+ if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
712
+ cls.push('focused');
713
+ // Compare internal UTC date with local today, not UTC today
714
+ if (this.o.todayHighlight &&
715
+ date.getUTCFullYear() === today.getFullYear() &&
716
+ date.getUTCMonth() === today.getMonth() &&
717
+ date.getUTCDate() === today.getDate()){
718
+ cls.push('today');
719
+ }
720
+ if (this.dates.contains(date) !== -1)
721
+ cls.push('active');
722
+ if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
723
+ $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){
724
+ cls.push('disabled');
725
+ }
726
+ if (this.range){
727
+ if (date > this.range[0] && date < this.range[this.range.length-1]){
728
+ cls.push('range');
729
+ }
730
+ if ($.inArray(date.valueOf(), this.range) !== -1){
731
+ cls.push('selected');
732
+ }
733
+ }
734
+ return cls;
735
+ },
736
+
737
+ fill: function(){
738
  var d = new Date(this.viewDate),
739
  year = d.getUTCFullYear(),
740
  month = d.getUTCMonth(),
741
+ startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
742
+ startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
743
+ endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
744
+ endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
745
+ todaytxt = dates[this.o.language].today || dates['en'].today || '',
746
+ cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
747
+ tooltip;
748
+ this.picker.find('.datepicker-days thead th.datepicker-switch')
749
+ .text(dates[this.o.language].months[month]+' '+year);
750
  this.picker.find('tfoot th.today')
751
+ .text(todaytxt)
752
+ .toggle(this.o.todayBtn !== false);
753
+ this.picker.find('tfoot th.clear')
754
+ .text(cleartxt)
755
+ .toggle(this.o.clearBtn !== false);
756
  this.updateNavArrows();
757
  this.fillMonths();
758
+ var prevMonth = UTCDate(year, month-1, 28),
759
  day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
760
  prevMonth.setUTCDate(day);
761
+ prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
762
  var nextMonth = new Date(prevMonth);
763
  nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
764
  nextMonth = nextMonth.valueOf();
765
  var html = [];
766
  var clsName;
767
+ while (prevMonth.valueOf() < nextMonth){
768
+ if (prevMonth.getUTCDay() === this.o.weekStart){
769
  html.push('<tr>');
770
+ if (this.o.calendarWeeks){
771
+ // ISO 8601: First week contains first thursday.
772
+ // ISO also states week starts on Monday, but we can be more abstract here.
773
+ var
774
+ // Start of current week: based on weekstart/current date
775
+ ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
776
+ // Thursday of this week
777
+ th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
778
+ // First Thursday of year, year from thursday
779
+ yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
780
+ // Calendar week: ms between thursdays, div ms per day, div 7 days
781
+ calWeek = (th - yth) / 864e5 / 7 + 1;
782
+ html.push('<td class="cw">'+ calWeek +'</td>');
783
+
784
+ }
785
  }
786
+ clsName = this.getClassNames(prevMonth);
787
+ clsName.push('day');
788
+
789
+ if (this.o.beforeShowDay !== $.noop){
790
+ var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
791
+ if (before === undefined)
792
+ before = {};
793
+ else if (typeof(before) === 'boolean')
794
+ before = {enabled: before};
795
+ else if (typeof(before) === 'string')
796
+ before = {classes: before};
797
+ if (before.enabled === false)
798
+ clsName.push('disabled');
799
+ if (before.classes)
800
+ clsName = clsName.concat(before.classes.split(/\s+/));
801
+ if (before.tooltip)
802
+ tooltip = before.tooltip;
 
 
803
  }
804
+
805
+ clsName = $.unique(clsName);
806
+ html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
807
+ if (prevMonth.getUTCDay() === this.o.weekEnd){
808
  html.push('</tr>');
809
  }
810
  prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
811
  }
812
  this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
 
813
 
814
  var months = this.picker.find('.datepicker-months')
815
  .find('th:eq(1)')
816
  .text(year)
817
  .end()
818
+ .find('span').removeClass('active');
819
+
820
+ $.each(this.dates, function(i, d){
821
+ if (d.getUTCFullYear() === year)
822
+ months.eq(d.getUTCMonth()).addClass('active');
823
+ });
824
+
825
+ if (year < startYear || year > endYear){
826
  months.addClass('disabled');
827
  }
828
+ if (year === startYear){
829
  months.slice(0, startMonth).addClass('disabled');
830
  }
831
+ if (year === endYear){
832
  months.slice(endMonth+1).addClass('disabled');
833
  }
834
 
840
  .end()
841
  .find('td');
842
  year -= 1;
843
+ var years = $.map(this.dates, function(d){
844
+ return d.getUTCFullYear();
845
+ }),
846
+ classes;
847
+ for (var i = -1; i < 11; i++){
848
+ classes = ['year'];
849
+ if (i === -1)
850
+ classes.push('old');
851
+ else if (i === 10)
852
+ classes.push('new');
853
+ if ($.inArray(year, years) !== -1)
854
+ classes.push('active');
855
+ if (year < startYear || year > endYear)
856
+ classes.push('disabled');
857
+ html += '<span class="' + classes.join(' ') + '">'+year+'</span>';
858
  year += 1;
859
  }
860
  yearCont.html(html);
861
  },
862
 
863
+ updateNavArrows: function(){
864
+ if (!this._allow_update)
865
+ return;
866
+
867
  var d = new Date(this.viewDate),
868
  year = d.getUTCFullYear(),
869
  month = d.getUTCMonth();
870
+ switch (this.viewMode){
871
  case 0:
872
+ if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
873
  this.picker.find('.prev').css({visibility: 'hidden'});
874
+ }
875
+ else {
876
  this.picker.find('.prev').css({visibility: 'visible'});
877
  }
878
+ if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
879
  this.picker.find('.next').css({visibility: 'hidden'});
880
+ }
881
+ else {
882
  this.picker.find('.next').css({visibility: 'visible'});
883
  }
884
  break;
885
  case 1:
886
  case 2:
887
+ if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){
888
  this.picker.find('.prev').css({visibility: 'hidden'});
889
+ }
890
+ else {
891
  this.picker.find('.prev').css({visibility: 'visible'});
892
  }
893
+ if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){
894
  this.picker.find('.next').css({visibility: 'hidden'});
895
+ }
896
+ else {
897
  this.picker.find('.next').css({visibility: 'visible'});
898
  }
899
  break;
900
  }
901
  },
902
 
903
+ click: function(e){
 
904
  e.preventDefault();
905
+ var target = $(e.target).closest('span, td, th'),
906
+ year, month, day;
907
+ if (target.length === 1){
908
+ switch (target[0].nodeName.toLowerCase()){
909
  case 'th':
910
+ switch (target[0].className){
911
+ case 'datepicker-switch':
912
  this.showMode(1);
913
  break;
914
  case 'prev':
915
  case 'next':
916
+ var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
917
+ switch (this.viewMode){
918
  case 0:
919
  this.viewDate = this.moveMonth(this.viewDate, dir);
920
+ this._trigger('changeMonth', this.viewDate);
921
  break;
922
  case 1:
923
  case 2:
924
  this.viewDate = this.moveYear(this.viewDate, dir);
925
+ if (this.viewMode === 1)
926
+ this._trigger('changeYear', this.viewDate);
927
  break;
928
  }
929
  this.fill();
930
  break;
931
  case 'today':
932
  var date = new Date();
933
+ date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
 
 
 
934
 
935
  this.showMode(-2);
936
+ var which = this.o.todayBtn === 'linked' ? null : 'view';
937
  this._setDate(date, which);
938
  break;
939
+ case 'clear':
940
+ var element;
941
+ if (this.isInput)
942
+ element = this.element;
943
+ else if (this.component)
944
+ element = this.element.find('input');
945
+ if (element)
946
+ element.val("").change();
947
+ this.update();
948
+ this._trigger('changeDate');
949
+ if (this.o.autoclose)
950
+ this.hide();
951
+ break;
952
  }
953
  break;
954
  case 'span':
955
+ if (!target.is('.disabled')){
956
  this.viewDate.setUTCDate(1);
957
+ if (target.is('.month')){
958
+ day = 1;
959
+ month = target.parent().find('span').index(target);
960
+ year = this.viewDate.getUTCFullYear();
961
  this.viewDate.setUTCMonth(month);
962
+ this._trigger('changeMonth', this.viewDate);
963
+ if (this.o.minViewMode === 1){
964
+ this._setDate(UTCDate(year, month, day));
965
+ }
966
+ }
967
+ else {
968
+ day = 1;
969
+ month = 0;
970
+ year = parseInt(target.text(), 10)||0;
971
  this.viewDate.setUTCFullYear(year);
972
+ this._trigger('changeYear', this.viewDate);
973
+ if (this.o.minViewMode === 2){
974
+ this._setDate(UTCDate(year, month, day));
975
+ }
976
  }
977
  this.showMode(-1);
978
  this.fill();
980
  break;
981
  case 'td':
982
  if (target.is('.day') && !target.is('.disabled')){
983
+ day = parseInt(target.text(), 10)||1;
984
+ year = this.viewDate.getUTCFullYear();
985
+ month = this.viewDate.getUTCMonth();
986
+ if (target.is('.old')){
987
+ if (month === 0){
988
  month = 11;
989
  year -= 1;
990
+ }
991
+ else {
992
  month -= 1;
993
  }
994
+ }
995
+ else if (target.is('.new')){
996
+ if (month === 11){
997
  month = 0;
998
  year += 1;
999
+ }
1000
+ else {
1001
  month += 1;
1002
  }
1003
  }
1004
+ this._setDate(UTCDate(year, month, day));
1005
  }
1006
  break;
1007
  }
1008
  }
1009
+ if (this.picker.is(':visible') && this._focused_from){
1010
+ $(this._focused_from).focus();
1011
+ }
1012
+ delete this._focused_from;
1013
+ },
1014
+
1015
+ _toggle_multidate: function(date){
1016
+ var ix = this.dates.contains(date);
1017
+ if (!date){
1018
+ this.dates.clear();
1019
+ }
1020
+ else if (ix !== -1){
1021
+ this.dates.remove(ix);
1022
+ }
1023
+ else {
1024
+ this.dates.push(date);
1025
+ }
1026
+ if (typeof this.o.multidate === 'number')
1027
+ while (this.dates.length > this.o.multidate)
1028
+ this.dates.remove(0);
1029
  },
1030
 
1031
  _setDate: function(date, which){
1032
+ if (!which || which === 'date')
1033
+ this._toggle_multidate(date && new Date(date));
1034
+ if (!which || which === 'view')
1035
+ this.viewDate = date && new Date(date);
1036
+
1037
  this.fill();
1038
  this.setValue();
1039
+ this._trigger('changeDate');
 
 
 
1040
  var element;
1041
+ if (this.isInput){
1042
  element = this.element;
1043
+ }
1044
+ else if (this.component){
1045
  element = this.element.find('input');
1046
  }
1047
+ if (element){
1048
  element.change();
1049
+ }
1050
+ if (this.o.autoclose && (!which || which === 'date')){
1051
+ this.hide();
1052
  }
1053
  },
1054
 
1055
  moveMonth: function(date, dir){
1056
+ if (!date)
1057
+ return undefined;
1058
+ if (!dir)
1059
+ return date;
1060
  var new_date = new Date(date.valueOf()),
1061
  day = new_date.getUTCDate(),
1062
  month = new_date.getUTCMonth(),
1063
  mag = Math.abs(dir),
1064
  new_month, test;
1065
  dir = dir > 0 ? 1 : -1;
1066
+ if (mag === 1){
1067
+ test = dir === -1
1068
  // If going back one month, make sure month is not current month
1069
  // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
1070
+ ? function(){
1071
+ return new_date.getUTCMonth() === month;
1072
+ }
1073
  // If going forward one month, make sure month is as expected
1074
  // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
1075
+ : function(){
1076
+ return new_date.getUTCMonth() !== new_month;
1077
+ };
1078
  new_month = month + dir;
1079
  new_date.setUTCMonth(new_month);
1080
  // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
1081
  if (new_month < 0 || new_month > 11)
1082
  new_month = (new_month + 12) % 12;
1083
+ }
1084
+ else {
1085
  // For magnitudes >1, move one month at a time...
1086
+ for (var i=0; i < mag; i++)
1087
  // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
1088
  new_date = this.moveMonth(new_date, dir);
1089
  // ...then reset the day, keeping it in the new month
1090
  new_month = new_date.getUTCMonth();
1091
  new_date.setUTCDate(day);
1092
+ test = function(){
1093
+ return new_month !== new_date.getUTCMonth();
1094
+ };
1095
  }
1096
  // Common date-resetting loop -- if date is beyond end of month, make it
1097
  // end of month
1107
  },
1108
 
1109
  dateWithinRange: function(date){
1110
+ return date >= this.o.startDate && date <= this.o.endDate;
1111
  },
1112
 
1113
  keydown: function(e){
1114
  if (this.picker.is(':not(:visible)')){
1115
+ if (e.keyCode === 27) // allow escape to hide and re-show picker
1116
  this.show();
1117
  return;
1118
  }
1119
  var dateChanged = false,
1120
+ dir, newDate, newViewDate,
1121
+ focusDate = this.focusDate || this.viewDate;
1122
+ switch (e.keyCode){
1123
  case 27: // escape
1124
+ if (this.focusDate){
1125
+ this.focusDate = null;
1126
+ this.viewDate = this.dates.get(-1) || this.viewDate;
1127
+ this.fill();
1128
+ }
1129
+ else
1130
+ this.hide();
1131
  e.preventDefault();
1132
  break;
1133
  case 37: // left
1134
  case 39: // right
1135
+ if (!this.o.keyboardNavigation)
1136
+ break;
1137
+ dir = e.keyCode === 37 ? -1 : 1;
1138
  if (e.ctrlKey){
1139
+ newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
1140
+ newViewDate = this.moveYear(focusDate, dir);
1141
+ this._trigger('changeYear', this.viewDate);
1142
+ }
1143
+ else if (e.shiftKey){
1144
+ newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
1145
+ newViewDate = this.moveMonth(focusDate, dir);
1146
+ this._trigger('changeMonth', this.viewDate);
1147
+ }
1148
+ else {
1149
+ newDate = new Date(this.dates.get(-1) || UTCToday());
1150
+ newDate.setUTCDate(newDate.getUTCDate() + dir);
1151
+ newViewDate = new Date(focusDate);
1152
+ newViewDate.setUTCDate(focusDate.getUTCDate() + dir);
1153
  }
1154
  if (this.dateWithinRange(newDate)){
1155
+ this.focusDate = this.viewDate = newViewDate;
 
1156
  this.setValue();
1157
+ this.fill();
1158
  e.preventDefault();
 
1159
  }
1160
  break;
1161
  case 38: // up
1162
  case 40: // down
1163
+ if (!this.o.keyboardNavigation)
1164
+ break;
1165
+ dir = e.keyCode === 38 ? -1 : 1;
1166
  if (e.ctrlKey){
1167
+ newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
1168
+ newViewDate = this.moveYear(focusDate, dir);
1169
+ this._trigger('changeYear', this.viewDate);
1170
+ }
1171
+ else if (e.shiftKey){
1172
+ newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
1173
+ newViewDate = this.moveMonth(focusDate, dir);
1174
+ this._trigger('changeMonth', this.viewDate);
1175
+ }
1176
+ else {
1177
+ newDate = new Date(this.dates.get(-1) || UTCToday());
1178
+ newDate.setUTCDate(newDate.getUTCDate() + dir * 7);
1179
+ newViewDate = new Date(focusDate);
1180
+ newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);
1181
  }
1182
  if (this.dateWithinRange(newDate)){
1183
+ this.focusDate = this.viewDate = newViewDate;
 
1184
  this.setValue();
1185
+ this.fill();
1186
  e.preventDefault();
 
1187
  }
1188
  break;
1189
+ case 32: // spacebar
1190
+ // Spacebar is used in manually typing dates in some formats.
1191
+ // As such, its behavior should not be hijacked.
1192
+ break;
1193
  case 13: // enter
1194
+ focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
1195
+ this._toggle_multidate(focusDate);
1196
+ dateChanged = true;
1197
+ this.focusDate = null;
1198
+ this.viewDate = this.dates.get(-1) || this.viewDate;
1199
+ this.setValue();
1200
+ this.fill();
1201
+ if (this.picker.is(':visible')){
1202
+ e.preventDefault();
1203
+ if (this.o.autoclose)
1204
+ this.hide();
1205
+ }
1206
  break;
1207
  case 9: // tab
1208
+ this.focusDate = null;
1209
+ this.viewDate = this.dates.get(-1) || this.viewDate;
1210
+ this.fill();
1211
  this.hide();
1212
  break;
1213
  }
1214
  if (dateChanged){
1215
+ if (this.dates.length)
1216
+ this._trigger('changeDate');
1217
+ else
1218
+ this._trigger('clearDate');
1219
  var element;
1220
+ if (this.isInput){
1221
  element = this.element;
1222
+ }
1223
+ else if (this.component){
1224
  element = this.element.find('input');
1225
  }
1226
+ if (element){
1227
  element.change();
1228
  }
1229
  }
1230
  },
1231
 
1232
+ showMode: function(dir){
1233
+ if (dir){
1234
+ this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
1235
  }
1236
+ this.picker
1237
+ .find('>div')
1238
+ .hide()
1239
+ .filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName)
1240
+ .css('display', 'block');
1241
  this.updateNavArrows();
1242
  }
1243
  };
1244
 
1245
+ var DateRangePicker = function(element, options){
1246
+ this.element = $(element);
1247
+ this.inputs = $.map(options.inputs, function(i){
1248
+ return i.jquery ? i[0] : i;
1249
+ });
1250
+ delete options.inputs;
1251
+
1252
+ $(this.inputs)
1253
+ .datepicker(options)
1254
+ .bind('changeDate', $.proxy(this.dateUpdated, this));
1255
+
1256
+ this.pickers = $.map(this.inputs, function(i){
1257
+ return $(i).data('datepicker');
1258
+ });
1259
+ this.updateDates();
1260
+ };
1261
+ DateRangePicker.prototype = {
1262
+ updateDates: function(){
1263
+ this.dates = $.map(this.pickers, function(i){
1264
+ return i.getUTCDate();
1265
+ });
1266
+ this.updateRanges();
1267
+ },
1268
+ updateRanges: function(){
1269
+ var range = $.map(this.dates, function(d){
1270
+ return d.valueOf();
1271
+ });
1272
+ $.each(this.pickers, function(i, p){
1273
+ p.setRange(range);
1274
+ });
1275
+ },
1276
+ dateUpdated: function(e){
1277
+ // `this.updating` is a workaround for preventing infinite recursion
1278
+ // between `changeDate` triggering and `setUTCDate` calling. Until
1279
+ // there is a better mechanism.
1280
+ if (this.updating)
1281
+ return;
1282
+ this.updating = true;
1283
+
1284
+ var dp = $(e.target).data('datepicker'),
1285
+ new_date = dp.getUTCDate(),
1286
+ i = $.inArray(e.target, this.inputs),
1287
+ l = this.inputs.length;
1288
+ if (i === -1)
1289
+ return;
1290
+
1291
+ $.each(this.pickers, function(i, p){
1292
+ if (!p.getUTCDate())
1293
+ p.setUTCDate(new_date);
1294
+ });
1295
+
1296
+ if (new_date < this.dates[i]){
1297
+ // Date being moved earlier/left
1298
+ while (i >= 0 && new_date < this.dates[i]){
1299
+ this.pickers[i--].setUTCDate(new_date);
1300
+ }
1301
+ }
1302
+ else if (new_date > this.dates[i]){
1303
+ // Date being moved later/right
1304
+ while (i < l && new_date > this.dates[i]){
1305
+ this.pickers[i++].setUTCDate(new_date);
1306
+ }
1307
+ }
1308
+ this.updateDates();
1309
+
1310
+ delete this.updating;
1311
+ },
1312
+ remove: function(){
1313
+ $.map(this.pickers, function(p){ p.remove(); });
1314
+ delete this.element.data().datepicker;
1315
+ }
1316
+ };
1317
+
1318
+ function opts_from_el(el, prefix){
1319
+ // Derive options from element data-attrs
1320
+ var data = $(el).data(),
1321
+ out = {}, inkey,
1322
+ replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
1323
+ prefix = new RegExp('^' + prefix.toLowerCase());
1324
+ function re_lower(_,a){
1325
+ return a.toLowerCase();
1326
+ }
1327
+ for (var key in data)
1328
+ if (prefix.test(key)){
1329
+ inkey = key.replace(replace, re_lower);
1330
+ out[inkey] = data[key];
1331
+ }
1332
+ return out;
1333
+ }
1334
+
1335
+ function opts_from_locale(lang){
1336
+ // Derive options from locale plugins
1337
+ var out = {};
1338
+ // Check if "de-DE" style date is available, if not language should
1339
+ // fallback to 2 letter code eg "de"
1340
+ if (!dates[lang]){
1341
+ lang = lang.split('-')[0];
1342
+ if (!dates[lang])
1343
+ return;
1344
+ }
1345
+ var d = dates[lang];
1346
+ $.each(locale_opts, function(i,k){
1347
+ if (k in d)
1348
+ out[k] = d[k];
1349
+ });
1350
+ return out;
1351
+ }
1352
+
1353
+ var old = $.fn.datepicker;
1354
+ $.fn.datepicker = function(option){
1355
  var args = Array.apply(null, arguments);
1356
  args.shift();
1357
+ var internal_return;
1358
+ this.each(function(){
1359
  var $this = $(this),
1360
  data = $this.data('datepicker'),
1361
+ options = typeof option === 'object' && option;
1362
+ if (!data){
1363
+ var elopts = opts_from_el(this, 'date'),
1364
+ // Preliminary otions
1365
+ xopts = $.extend({}, defaults, elopts, options),
1366
+ locopts = opts_from_locale(xopts.language),
1367
+ // Options priority: js args, data-attrs, locales, defaults
1368
+ opts = $.extend({}, defaults, locopts, elopts, options);
1369
+ if ($this.is('.input-daterange') || opts.inputs){
1370
+ var ropts = {
1371
+ inputs: opts.inputs || $this.find('input').toArray()
1372
+ };
1373
+ $this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
1374
+ }
1375
+ else {
1376
+ $this.data('datepicker', (data = new Datepicker(this, opts)));
1377
+ }
1378
  }
1379
+ if (typeof option === 'string' && typeof data[option] === 'function'){
1380
+ internal_return = data[option].apply(data, args);
1381
+ if (internal_return !== undefined)
1382
+ return false;
1383
  }
1384
  });
1385
+ if (internal_return !== undefined)
1386
+ return internal_return;
1387
+ else
1388
+ return this;
1389
  };
1390
 
1391
+ var defaults = $.fn.datepicker.defaults = {
1392
+ autoclose: false,
1393
+ beforeShowDay: $.noop,
1394
+ calendarWeeks: false,
1395
+ clearBtn: false,
1396
+ daysOfWeekDisabled: [],
1397
+ endDate: Infinity,
1398
+ forceParse: true,
1399
+ format: 'mm/dd/yyyy',
1400
+ keyboardNavigation: true,
1401
+ language: 'en',
1402
+ minViewMode: 0,
1403
+ multidate: false,
1404
+ multidateSeparator: ',',
1405
+ orientation: "auto",
1406
+ rtl: false,
1407
+ startDate: -Infinity,
1408
+ startView: 0,
1409
+ todayBtn: false,
1410
+ todayHighlight: false,
1411
+ weekStart: 0
1412
  };
1413
+ var locale_opts = $.fn.datepicker.locale_opts = [
1414
+ 'format',
1415
+ 'rtl',
1416
+ 'weekStart'
1417
+ ];
1418
  $.fn.datepicker.Constructor = Datepicker;
1419
  var dates = $.fn.datepicker.dates = {
1420
  en: {
1423
  daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
1424
  months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
1425
  monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1426
+ today: "Today",
1427
+ clear: "Clear"
1428
  }
1429
+ };
1430
 
1431
  var DPGlobal = {
1432
  modes: [
1445
  navFnc: 'FullYear',
1446
  navStep: 10
1447
  }],
1448
+ isLeapYear: function(year){
1449
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
1450
  },
1451
+ getDaysInMonth: function(year, month){
1452
+ return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
1453
  },
1454
+ validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1455
+ nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
1456
  parseFormat: function(format){
1457
  // IE treats \0 as a string end in inputs (truncating the value),
1458
  // so it's a bad format delimiter, anyway
1459
  var separators = format.replace(this.validParts, '\0').split('\0'),
1460
  parts = format.match(this.validParts);
1461
+ if (!separators || !separators.length || !parts || parts.length === 0){
1462
  throw new Error("Invalid date format.");
1463
  }
1464
  return {separators: separators, parts: parts};
1465
  },
1466
+ parseDate: function(date, format, language){
1467
+ if (!date)
1468
+ return undefined;
1469
+ if (date instanceof Date)
1470
+ return date;
1471
+ if (typeof format === 'string')
1472
+ format = DPGlobal.parseFormat(format);
1473
+ var part_re = /([\-+]\d+)([dmwy])/,
1474
+ parts = date.match(/([\-+]\d+)([dmwy])/g),
1475
+ part, dir, i;
1476
+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
1477
  date = new Date();
1478
+ for (i=0; i < parts.length; i++){
1479
  part = part_re.exec(parts[i]);
1480
  dir = parseInt(part[1]);
1481
+ switch (part[2]){
1482
  case 'd':
1483
  date.setUTCDate(date.getUTCDate() + dir);
1484
  break;
1495
  }
1496
  return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
1497
  }
1498
+ parts = date && date.match(this.nonpunctuation) || [];
1499
+ date = new Date();
1500
+ var parsed = {},
1501
  setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
1502
  setters_map = {
1503
+ yyyy: function(d,v){
1504
+ return d.setUTCFullYear(v);
1505
+ },
1506
+ yy: function(d,v){
1507
+ return d.setUTCFullYear(2000+v);
1508
+ },
1509
  m: function(d,v){
1510
+ if (isNaN(d))
1511
+ return d;
1512
  v -= 1;
1513
+ while (v < 0) v += 12;
1514
  v %= 12;
1515
  d.setUTCMonth(v);
1516
+ while (d.getUTCMonth() !== v)
1517
  d.setUTCDate(d.getUTCDate()-1);
1518
  return d;
1519
  },
1520
+ d: function(d,v){
1521
+ return d.setUTCDate(v);
1522
+ }
1523
  },
1524
+ val, filtered;
1525
  setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1526
  setters_map['dd'] = setters_map['d'];
1527
  date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
1528
+ var fparts = format.parts.slice();
1529
+ // Remove noop parts
1530
+ if (parts.length !== fparts.length){
1531
+ fparts = $(fparts).filter(function(i,p){
1532
+ return $.inArray(p, setters_order) !== -1;
1533
+ }).toArray();
1534
+ }
1535
+ // Process remainder
1536
+ function match_part(){
1537
+ var m = this.slice(0, parts[i].length),
1538
+ p = parts[i].slice(0, m.length);
1539
+ return m === p;
1540
+ }
1541
+ if (parts.length === fparts.length){
1542
+ var cnt;
1543
+ for (i=0, cnt = fparts.length; i < cnt; i++){
1544
  val = parseInt(parts[i], 10);
1545
+ part = fparts[i];
1546
+ if (isNaN(val)){
1547
+ switch (part){
1548
  case 'MM':
1549
+ filtered = $(dates[language].months).filter(match_part);
 
 
 
 
1550
  val = $.inArray(filtered[0], dates[language].months) + 1;
1551
  break;
1552
  case 'M':
1553
+ filtered = $(dates[language].monthsShort).filter(match_part);
 
 
 
 
1554
  val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
1555
  break;
1556
  }
1557
  }
1558
  parsed[part] = val;
1559
  }
1560
+ var _date, s;
1561
+ for (i=0; i < setters_order.length; i++){
1562
  s = setters_order[i];
1563
+ if (s in parsed && !isNaN(parsed[s])){
1564
+ _date = new Date(date);
1565
+ setters_map[s](_date, parsed[s]);
1566
+ if (!isNaN(_date))
1567
+ date = _date;
1568
+ }
1569
  }
1570
  }
1571
  return date;
1572
  },
1573
  formatDate: function(date, format, language){
1574
+ if (!date)
1575
+ return '';
1576
+ if (typeof format === 'string')
1577
+ format = DPGlobal.parseFormat(format);
1578
  var val = {
1579
  d: date.getUTCDate(),
1580
+ D: dates[language].daysShort[date.getUTCDay()],
1581
+ DD: dates[language].days[date.getUTCDay()],
1582
  m: date.getUTCMonth() + 1,
1583
  M: dates[language].monthsShort[date.getUTCMonth()],
1584
  MM: dates[language].months[date.getUTCMonth()],
1587
  };
1588
  val.dd = (val.d < 10 ? '0' : '') + val.d;
1589
  val.mm = (val.m < 10 ? '0' : '') + val.m;
1590
+ date = [];
1591
+ var seps = $.extend([], format.separators);
1592
+ for (var i=0, cnt = format.parts.length; i <= cnt; i++){
1593
  if (seps.length)
1594
+ date.push(seps.shift());
1595
  date.push(val[format.parts[i]]);
1596
  }
1597
  return date.join('');
1598
  },
1599
  headTemplate: '<thead>'+
1600
  '<tr>'+
1601
+ '<th class="prev">&laquo;</th>'+
1602
+ '<th colspan="5" class="datepicker-switch"></th>'+
1603
+ '<th class="next">&raquo;</th>'+
1604
  '</tr>'+
1605
  '</thead>',
1606
  contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1607
+ footTemplate: '<tfoot>'+
1608
+ '<tr>'+
1609
+ '<th colspan="7" class="today"></th>'+
1610
+ '</tr>'+
1611
+ '<tr>'+
1612
+ '<th colspan="7" class="clear"></th>'+
1613
+ '</tr>'+
1614
+ '</tfoot>'
1615
  };
1616
+ DPGlobal.template = '<div class="datepicker">'+
1617
  '<div class="datepicker-days">'+
1618
  '<table class=" table-condensed">'+
1619
  DPGlobal.headTemplate+
1636
  '</table>'+
1637
  '</div>'+
1638
  '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1639
 
1640
+ $.fn.datepicker.DPGlobal = DPGlobal;
1641
 
1642
 
1643
+ /* DATEPICKER NO CONFLICT
1644
+ * =================== */
1645
 
1646
+ $.fn.datepicker.noConflict = function(){
1647
+ $.fn.datepicker = old;
1648
+ return this;
1649
+ };
1650
 
1651
 
1652
+ /* DATEPICKER DATA-API
1653
+ * ================== */
1654
 
1655
+ $(document).on(
1656
+ 'focus.datepicker.data-api click.datepicker.data-api',
1657
+ '[data-provide="datepicker"]',
1658
+ function(e){
1659
+ var $this = $(this);
1660
+ if ($this.data('datepicker'))
1661
+ return;
1662
+ e.preventDefault();
1663
+ // component click requires us to explicitly show it
1664
+ $this.datepicker('show');
1665
+ }
1666
+ );
1667
+ $(function(){
1668
+ $('[data-provide="datepicker-inline"]').datepicker();
1669
+ });
1670
 
1671
+ }(window.jQuery));
fields/date_picker/setup.html CHANGED
@@ -1,7 +1,7 @@
1
  <div class="caldera-config-group">
2
  <label>Default</label>
3
  <div class="caldera-config-field">
4
- <input type="text" class="block-input field-config is-datepicker" id="{{id}}" data-date-format="{{format}}" name="{{_name}}[default]" value="{{default}}">
5
  </div>
6
  </div>
7
  <div class="caldera-config-group">
1
  <div class="caldera-config-group">
2
  <label>Default</label>
3
  <div class="caldera-config-field">
4
+ <input type="text" class="block-input field-config is-datepicker" data-provide="datepicker" id="{{id}}" data-date-format="{{format}}" name="{{_name}}[default]" value="{{default}}">
5
  </div>
6
  </div>
7
  <div class="caldera-config-group">
fields/dropdown/field.php CHANGED
@@ -3,8 +3,18 @@
3
  <div class="<?php echo $field_input_class; ?>">
4
  <select <?php echo $field_placeholder; ?> id="<?php echo $field_id; ?>" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" name="<?php echo $field_name; ?>" <?php echo $field_required; ?>>
5
  <?php
 
6
  if(!empty($field['config']['option'])){
 
 
 
 
 
7
  foreach($field['config']['option'] as $option_key=>$option){
 
 
 
 
8
  ?>
9
  <option value="<?php echo $option['value']; ?>" <?php if( $field_value == $option['value'] ){ ?>selected="true"<?php } ?>><?php echo $option['label']; ?></option>
10
  <?php
3
  <div class="<?php echo $field_input_class; ?>">
4
  <select <?php echo $field_placeholder; ?> id="<?php echo $field_id; ?>" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" name="<?php echo $field_name; ?>" <?php echo $field_required; ?>>
5
  <?php
6
+
7
  if(!empty($field['config']['option'])){
8
+ if(!empty($field['config']['default'])){
9
+ if(!isset($field['config']['option'][$field['config']['default']])){
10
+ echo "<option value=\"\"></option>\r\n";
11
+ }
12
+ }
13
  foreach($field['config']['option'] as $option_key=>$option){
14
+ if(!isset($option['value'])){
15
+ $option['value'] = htmlspecialchars( $option['label'] );
16
+ }
17
+
18
  ?>
19
  <option value="<?php echo $option['value']; ?>" <?php if( $field_value == $option['value'] ){ ?>selected="true"<?php } ?>><?php echo $option['label']; ?></option>
20
  <?php
fields/email/config.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="caldera-config-group">
2
+ <label>Placeholder</label>
3
+ <div class="caldera-config-field">
4
+ <input type="text" id="{{_id}}_placeholder" class="block-input field-config" name="{{_name}}[placeholder]" value="{{placeholder}}">
5
+ </div>
6
+ </div>
7
+ <div class="caldera-config-group">
8
+ <label>Default</label>
9
+ <div class="caldera-config-field">
10
+ <input type="text" id="{{_id}}_default" class="block-input field-config" name="{{_name}}[default]" value="{{default}}">
11
+ </div>
12
+ </div>
fields/email/field.php CHANGED
@@ -1,4 +1,9 @@
1
- <div class="<?php echo $field_wrapper_class; ?>">
 
 
 
 
 
2
  <?php echo $field_label; ?>
3
  <div class="<?php echo $field_input_class; ?>">
4
  <input <?php echo $field_placeholder; ?> type="email" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" id="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo htmlentities( $field_value ); ?>" <?php echo $field_required; ?>>
1
+ <?php
2
+ if(!empty($field['config']['placeholder'])){
3
+ $field_placeholder = 'placeholder="'.$field['config']['placeholder'].'"';
4
+ }
5
+
6
+ ?><div class="<?php echo $field_wrapper_class; ?>">
7
  <?php echo $field_label; ?>
8
  <div class="<?php echo $field_input_class; ?>">
9
  <input <?php echo $field_placeholder; ?> type="email" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" id="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo htmlentities( $field_value ); ?>" <?php echo $field_required; ?>>
fields/email/preview.php CHANGED
@@ -1,7 +1,7 @@
1
  <div class="preview-caldera-config-group">
2
  {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
  <div class="preview-caldera-config-field">
4
- <input {{#if hide_label}}placeholder="{{label}}"{{/if}} type="email" class="preview-field-config" value="{{config/default}}">
5
  <span class="help-block">{{caption}}</span>
6
  </div>
7
  </div>
1
  <div class="preview-caldera-config-group">
2
  {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
  <div class="preview-caldera-config-field">
4
+ <input {{#if hide_label}}placeholder="{{label}}"{{else}}placeholder="{{config/placeholder}}"{{/if}} type="email" class="preview-field-config" value="{{config/default}}">
5
  <span class="help-block">{{caption}}</span>
6
  </div>
7
  </div>
fields/html/config_template.php CHANGED
@@ -1,4 +1,4 @@
1
  <div class="caldera-config-group">
2
  <label>Default</label>
3
  </div>
4
- <textarea class="block-input field-config" name="{{_name}}[default]" style="resize:vertical; height:200px;">{{default}}</textarea>
1
  <div class="caldera-config-group">
2
  <label>Default</label>
3
  </div>
4
+ <textarea class="block-input field-config" name="{{_name}}[default]" id="{{_id}}editor" style="resize:vertical; height:200px;">{{default}}</textarea>
fields/html/field.php CHANGED
@@ -1 +1,51 @@
1
- <?php echo $field['config']['default']; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // magics!
3
+ $field['config']['default'] = self::do_magic_tags($field['config']['default']);
4
+
5
+ preg_match_all("/%(.+?)%/", $field['config']['default'], $hastags);
6
+ if(!empty($hastags[1])){
7
+ $binds = array();
8
+
9
+ foreach($hastags[1] as $tag_key=>$tag){
10
+
11
+ foreach($form['fields'] as $key_id=>$fcfg){
12
+ if($fcfg['slug'] === $tag){
13
+ $binds[] = '[data-field="'.$key_id.'"]';
14
+ $bindfields[] = '"'.$key_id.'"';
15
+ $field['config']['default'] = str_replace($hastags[0][$tag_key], '{{'.$key_id.'}}', $field['config']['default']);
16
+ }
17
+ }
18
+ }
19
+ echo '<div id="html-content-'.$field_id.'" data-field="'.$field_id.'"></div>';
20
+ echo '<script type="text/html" id="html-content-'.$field_id.'-tmpl">';
21
+ echo do_shortcode( $field['config']['default'] );
22
+ echo '</script>';
23
+ ?>
24
+ <script type="text/javascript">
25
+ jQuery(function($){
26
+
27
+ function htmltemplate<?php echo $field_id; ?>(){
28
+
29
+ var template = $('#html-content-<?php echo $field_id; ?>-tmpl').html(),
30
+ target = $('#html-content-<?php echo $field_id; ?>'),
31
+ list = [<?php echo implode(',', $bindfields); ?>];
32
+
33
+ for(var i =0; i < list.length; i++){
34
+ template = template.replace( new RegExp("\{\{" + list[i] + "\}\}","g"), $('[data-field="'+list[i]+'"]').val() );
35
+ }
36
+ target.html(template).trigger('change');
37
+
38
+ }
39
+ $('body').on('change', '<?php echo implode(',', $binds); ?>', htmltemplate<?php echo $field_id; ?>);
40
+
41
+ htmltemplate<?php echo $field_id; ?>();
42
+
43
+ })
44
+ </script>
45
+ <?php
46
+ }else{
47
+ echo do_shortcode( $field['config']['default'] );
48
+ }
49
+
50
+
51
+ ?>
fields/image_picker/js/admin.js CHANGED
@@ -219,7 +219,7 @@ jQuery(function($){
219
  value.prop('disabled', false);
220
  value.val(attachment.id);
221
  thumbnail_val.prop('disabled', false);
222
- console.log(thumbnail_val);
223
  if(picksize.hasClass('image-thumb-lrg')){
224
  if(attachment.sizes.large){
225
  thumbnail.attr('src', attachment.sizes.large.url);
219
  value.prop('disabled', false);
220
  value.val(attachment.id);
221
  thumbnail_val.prop('disabled', false);
222
+
223
  if(picksize.hasClass('image-thumb-lrg')){
224
  if(attachment.sizes.large){
225
  thumbnail.attr('src', attachment.sizes.large.url);
fields/paragraph/config_template.html CHANGED
@@ -1,3 +1,9 @@
 
 
 
 
 
 
1
  <div class="caldera-config-group">
2
  <label>Rows</label>
3
  <div class="caldera-config-field">
@@ -7,6 +13,6 @@
7
  <div class="caldera-config-group">
8
  <label>Default</label>
9
  <div class="caldera-config-field">
10
- <textarea class="block-input field-config" name="{{_name}}[default]">{{value}}</textarea>
11
  </div>
12
  </div>
1
+ <div class="caldera-config-group">
2
+ <label>Placeholder</label>
3
+ <div class="caldera-config-field">
4
+ <input type="text" id="{{_id}}_placeholder" class="block-input field-config" name="{{_name}}[placeholder]" value="{{placeholder}}">
5
+ </div>
6
+ </div>
7
  <div class="caldera-config-group">
8
  <label>Rows</label>
9
  <div class="caldera-config-field">
13
  <div class="caldera-config-group">
14
  <label>Default</label>
15
  <div class="caldera-config-field">
16
+ <textarea class="block-input field-config" name="{{_name}}[default]">{{default}}</textarea>
17
  </div>
18
  </div>
fields/paragraph/field.php CHANGED
@@ -1,4 +1,8 @@
1
- <div class="<?php echo $field_wrapper_class; ?>">
 
 
 
 
2
  <?php echo $field_label; ?>
3
  <div class="<?php echo $field_input_class; ?>">
4
  <textarea <?php echo $field_placeholder; ?> data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" rows="<?php echo $field['config']['rows']; ?>" id="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" <?php echo $field_required; ?>><?php echo htmlentities( $field_value ); ?></textarea>
1
+ <?php
2
+ if(!empty($field['config']['placeholder'])){
3
+ $field_placeholder = 'placeholder="'.$field['config']['placeholder'].'"';
4
+ }
5
+ ?><div class="<?php echo $field_wrapper_class; ?>">
6
  <?php echo $field_label; ?>
7
  <div class="<?php echo $field_input_class; ?>">
8
  <textarea <?php echo $field_placeholder; ?> data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" rows="<?php echo $field['config']['rows']; ?>" id="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" <?php echo $field_required; ?>><?php echo htmlentities( $field_value ); ?></textarea>
fields/paragraph/preview.php CHANGED
@@ -1,7 +1,7 @@
1
  <div class="preview-caldera-config-group">
2
  {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
  <div class="preview-caldera-config-field">
4
- <textarea {{#if hide_label}}placeholder="{{label}}"{{/if}} rows="{{config/rows}}" style="resize:none;" class="preview-field-config">{{config/default}}</textarea>
5
  <span class="help-block">{{caption}}</span>
6
  </div>
7
  </div>
1
  <div class="preview-caldera-config-group">
2
  {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
  <div class="preview-caldera-config-field">
4
+ <textarea {{#if hide_label}}placeholder="{{label}}"{{else}}placeholder="{{config/placeholder}}"{{/if}} rows="{{config/rows}}" style="resize:none;" class="preview-field-config">{{config/default}}</textarea>
5
  <span class="help-block">{{caption}}</span>
6
  </div>
7
  </div>
fields/phone/config.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="caldera-config-group">
2
+ <label>Placeholder</label>
3
+ <div class="caldera-config-field">
4
+ <input type="text" id="{{_id}}_placeholder" class="block-input field-config" name="{{_name}}[placeholder]" value="{{placeholder}}">
5
+ </div>
6
+ </div>
7
+ <div class="caldera-config-group">
8
+ <label>Default</label>
9
+ <div class="caldera-config-field">
10
+ <input type="text" id="{{_id}}_default" class="block-input field-config" name="{{_name}}[default]" value="{{default}}">
11
+ </div>
12
+ </div>
13
+ <div class="caldera-config-group">
14
+ <label>Style</label>
15
+ <div class="caldera-config-field">
16
+ <label><input type="radio" class="field-config {{_id}}_type local" name="{{_name}}[type]" value="local" {{#is type value="local"}}checked="checked"{{/is}}> Local</label>
17
+ <p class="description">(999)999-9999</p>
18
+ <label><input type="radio" class="field-config {{_id}}_type international" name="{{_name}}[type]" value="international" {{#is type value="international"}}checked="checked"{{/is}}> International</label>
19
+ <p class="description">+99 (9)99 999-9999</p>
20
+ <label><input type="radio" class="field-config {{_id}}_type custom" name="{{_name}}[type]" value="custom" {{#is type value="custom"}}checked="checked"{{/is}}> Custom</label>
21
+ <p class="description"><input type="text" id="{{_id}}_custom" class="field-config" name="{{_name}}[custom]" value="{{custom}}"></p>
22
+ <p class="description"><?php echo __('Use the digit 9 to indicate a number', 'caldera-forms'); ?></p>
23
+ </div>
24
+ </div>
25
+
26
+ {{#script}}
27
+ jQuery(function($){
28
+
29
+ $('.{{_id}}_type').change(function(){
30
+
31
+ if(this.value === 'local'){
32
+ $('#{{_id}}_default').inputmask("(999)999-9999");
33
+ }else if(this.value === 'international'){
34
+ $('#{{_id}}_default').inputmask("+99 (9)99 999-9999");
35
+ }else if(this.value === 'custom'){
36
+ $('#{{_id}}_default').inputmask( $('#{{_id}}_custom').val() );
37
+ }
38
+ });
39
+ $('#{{_id}}_custom').change(function(){
40
+ $('.{{_id}}_type.{{type}}').trigger('change');
41
+ });
42
+ $('.{{_id}}_type.{{type}}').trigger('change');
43
+ });
44
+ {{/script}}
fields/phone/field.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if(!empty($field['config']['placeholder'])){
3
+ $field_placeholder = 'placeholder="'.$field['config']['placeholder'].'"';
4
+ }
5
+
6
+ $mask = '(999)999-9999';
7
+ if($field['config']['type'] == 'international'){
8
+ $mask = '+99 (9)99 999-9999';
9
+ }
10
+
11
+ ?><div class="<?php echo $field_wrapper_class; ?>">
12
+ <?php echo $field_label; ?>
13
+ <div class="<?php echo $field_input_class; ?>">
14
+ <input <?php echo $field_placeholder; ?> type="text" data-inputmask="'mask': '<?php echo $mask; ?>'" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" id="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo htmlentities( $field_value ); ?>" <?php echo $field_required; ?>>
15
+ <?php echo $field_caption; ?>
16
+ </div>
17
+ </div>
fields/phone/masked-input.js ADDED
@@ -0,0 +1,1652 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @license Input Mask plugin for jquery
3
+ * http://github.com/RobinHerbots/jquery.inputmask
4
+ * Copyright (c) 2010 - 2014 Robin Herbots
5
+ * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
6
+ * Version: 0.0.0
7
+ */
8
+
9
+ (function ($) {
10
+ if ($.fn.inputmask === undefined) {
11
+
12
+ //helper functions
13
+ function isInputEventSupported(eventName) {
14
+ var el = document.createElement('input'),
15
+ eventName = 'on' + eventName,
16
+ isSupported = (eventName in el);
17
+ if (!isSupported) {
18
+ el.setAttribute(eventName, 'return;');
19
+ isSupported = typeof el[eventName] == 'function';
20
+ }
21
+ el = null;
22
+ return isSupported;
23
+ }
24
+
25
+ function resolveAlias(aliasStr, options, opts) {
26
+ var aliasDefinition = opts.aliases[aliasStr];
27
+ if (aliasDefinition) {
28
+ if (aliasDefinition.alias) resolveAlias(aliasDefinition.alias, undefined, opts); //alias is another alias
29
+ $.extend(true, opts, aliasDefinition); //merge alias definition in the options
30
+ $.extend(true, opts, options); //reapply extra given options
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+
36
+ function generateMaskSet(opts) {
37
+ var ms = [];
38
+
39
+ function analyseMask(mask) {
40
+ var tokenizer = /(?:[?*+]|\{[0-9\+\*]+(?:,[0-9\+\*]*)?\})\??|[^.?*+^${[]()|\\]+|./g,
41
+ escaped = false;
42
+
43
+ function maskToken(isGroup, isOptional, isQuantifier, isAlternator) {
44
+ this.matches = [];
45
+ this.isGroup = isGroup || false;
46
+ this.isOptional = isOptional || false;
47
+ this.isQuantifier = isQuantifier || false;
48
+ this.isAlternator = isAlternator || false;
49
+ this.quantifier = { min: 1, max: 1 };
50
+ };
51
+
52
+ //test definition => {fn: RegExp/function, cardinality: int, optionality: bool, newBlockMarker: bool, offset: int, casing: null/upper/lower, def: definitionSymbol}
53
+ function insertTestDefinition(mtoken, element, position) {
54
+ var maskdef = opts.definitions[element];
55
+ var newBlockMarker = mtoken.matches.length == 0;
56
+ position = position != undefined ? position : mtoken.matches.length;
57
+ if (maskdef && !escaped) {
58
+ var prevalidators = maskdef["prevalidator"], prevalidatorsL = prevalidators ? prevalidators.length : 0;
59
+ for (var i = 1; i < maskdef.cardinality; i++) {
60
+ var prevalidator = prevalidatorsL >= i ? prevalidators[i - 1] : [], validator = prevalidator["validator"], cardinality = prevalidator["cardinality"];
61
+ mtoken.matches.splice(position++, 0, { fn: validator ? typeof validator == 'string' ? new RegExp(validator) : new function () { this.test = validator; } : new RegExp("."), cardinality: cardinality ? cardinality : 1, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element });
62
+ }
63
+ mtoken.matches.splice(position++, 0, { fn: maskdef.validator ? typeof maskdef.validator == 'string' ? new RegExp(maskdef.validator) : new function () { this.test = maskdef.validator; } : new RegExp("."), cardinality: maskdef.cardinality, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element });
64
+ } else {
65
+ mtoken.matches.splice(position++, 0, { fn: null, cardinality: 0, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: null, def: element });
66
+ escaped = false;
67
+ }
68
+ }
69
+
70
+ var currentToken = new maskToken(),
71
+ match,
72
+ m,
73
+ openenings = [],
74
+ maskTokens = [];
75
+
76
+ while (match = tokenizer.exec(mask)) {
77
+ m = match[0];
78
+ switch (m.charAt(0)) {
79
+ case opts.optionalmarker.end:
80
+ // optional closing
81
+ case opts.groupmarker.end:
82
+ // Group closing
83
+ var openingToken = openenings.pop();
84
+ if (openenings.length > 0) {
85
+ openenings[openenings.length - 1]["matches"].push(openingToken);
86
+ } else {
87
+ currentToken.matches.push(openingToken);
88
+ }
89
+ break;
90
+ case opts.optionalmarker.start:
91
+ // optional opening
92
+ openenings.push(new maskToken(false, true));
93
+ break;
94
+ case opts.groupmarker.start:
95
+ // Group opening
96
+ openenings.push(new maskToken(true));
97
+ break;
98
+ case opts.quantifiermarker.start:
99
+ //Quantifier
100
+ var quantifier = new maskToken(false, false, true);
101
+
102
+ m = m.replace(/[{}]/g, "");
103
+ var mq = m.split(","),
104
+ mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]),
105
+ mq1 = mq.length == 1 ? mq0 : (isNaN(mq[1]) ? mq[1] : parseInt(mq[1]));
106
+ if (mq1 == "*" || mq1 == "+") {
107
+ mq0 = mq1 == "*" ? 0 : 1;
108
+ }
109
+ quantifier.quantifier = { min: mq0, max: mq1 };
110
+ if (openenings.length > 0) {
111
+ var matches = openenings[openenings.length - 1]["matches"];
112
+ var match = matches.pop();
113
+ if (!match["isGroup"]) {
114
+ var groupToken = new maskToken(true);
115
+ groupToken.matches.push(match);
116
+ match = groupToken;
117
+ }
118
+ matches.push(match);
119
+ matches.push(quantifier);
120
+ } else {
121
+ var match = currentToken.matches.pop();
122
+ if (!match["isGroup"]) {
123
+ var groupToken = new maskToken(true);
124
+ groupToken.matches.push(match);
125
+ match = groupToken;
126
+ }
127
+ currentToken.matches.push(match);
128
+ currentToken.matches.push(quantifier);
129
+ }
130
+ break;
131
+ case opts.escapeChar:
132
+ escaped = true;
133
+ break;
134
+ case opts.alternatormarker:
135
+
136
+ break;
137
+ default:
138
+ if (openenings.length > 0) {
139
+ insertTestDefinition(openenings[openenings.length - 1], m);
140
+ } else {
141
+ if (currentToken.matches.length > 0) {
142
+ var lastMatch = currentToken.matches[currentToken.matches.length - 1];
143
+ if (lastMatch["isGroup"]) { //this is not a group but a normal mask => convert
144
+ lastMatch.isGroup = false;
145
+ insertTestDefinition(lastMatch, opts.groupmarker.start, 0);
146
+ insertTestDefinition(lastMatch, opts.groupmarker.end);
147
+ }
148
+ }
149
+ insertTestDefinition(currentToken, m);
150
+ }
151
+ }
152
+ }
153
+
154
+ if (currentToken.matches.length > 0) {
155
+ var lastMatch = currentToken.matches[currentToken.matches.length - 1];
156
+ if (lastMatch["isGroup"]) { //this is not a group but a normal mask => convert
157
+ lastMatch.isGroup = false;
158
+ insertTestDefinition(lastMatch, opts.groupmarker.start, 0);
159
+ insertTestDefinition(lastMatch, opts.groupmarker.end);
160
+ }
161
+ maskTokens.push(currentToken);
162
+ }
163
+
164
+ //console.log(JSON.stringify(maskTokens));
165
+ return maskTokens;
166
+ }
167
+
168
+ function generateMask(mask, metadata) {
169
+ if (opts.numericInput && opts.multi !== true) { //TODO FIX FOR DYNAMIC MASKS WITH QUANTIFIERS
170
+ mask = mask.split('').reverse();
171
+ for (var ndx = 0; ndx < mask.length; ndx++) {
172
+ if (mask[ndx] == opts.optionalmarker.start)
173
+ mask[ndx] = opts.optionalmarker.end;
174
+ else if (mask[ndx] == opts.optionalmarker.end)
175
+ mask[ndx] = opts.optionalmarker.start;
176
+ else if (mask[ndx] == opts.groupmarker.start)
177
+ mask[ndx] = opts.groupmarker.end;
178
+ else if (mask[ndx] == opts.groupmarker.end)
179
+ mask[ndx] = opts.groupmarker.start;
180
+ }
181
+ mask = mask.join('');
182
+ }
183
+ if (mask == undefined || mask == "")
184
+ return undefined;
185
+ else {
186
+ if (opts.repeat > 0 || opts.repeat == "*" || opts.repeat == "+") {
187
+ var repeatStart = opts.repeat == "*" ? 0 : (opts.repeat == "+" ? 1 : opts.repeat);
188
+ mask = opts.groupmarker.start + mask + opts.groupmarker.end + opts.quantifiermarker.start + repeatStart + "," + opts.repeat + opts.quantifiermarker.end;
189
+ }
190
+ if ($.inputmask.masksCache[mask] == undefined) {
191
+ $.inputmask.masksCache[mask] = {
192
+ "mask": mask,
193
+ "maskToken": analyseMask(mask),
194
+ "validPositions": {},
195
+ "_buffer": undefined,
196
+ "buffer": undefined,
197
+ "tests": {},
198
+ "metadata": metadata
199
+ };
200
+ }
201
+
202
+ return $.extend(true, {}, $.inputmask.masksCache[mask]);
203
+ }
204
+ }
205
+
206
+ if ($.isFunction(opts.mask)) { //allow mask to be a preprocessing fn - should return a valid mask
207
+ opts.mask = opts.mask.call(this, opts);
208
+ }
209
+ if ($.isArray(opts.mask)) {
210
+ $.each(opts.mask, function (ndx, msk) {
211
+ if (msk["mask"] != undefined) {
212
+ ms.push(generateMask(msk["mask"].toString(), msk));
213
+ } else {
214
+ ms.push(generateMask(msk.toString()));
215
+ }
216
+ });
217
+ } else {
218
+ if (opts.mask.length == 1 && opts.greedy == false && opts.repeat != 0) {
219
+ opts.placeholder = "";
220
+ } //hide placeholder with single non-greedy mask
221
+ if (opts.mask["mask"] != undefined) {
222
+ ms = generateMask(opts.mask["mask"].toString(), opts.mask);
223
+ } else {
224
+ ms = generateMask(opts.mask.toString());
225
+ }
226
+ }
227
+ return ms;
228
+ }
229
+
230
+ var msie1x = typeof ScriptEngineMajorVersion === "function"
231
+ ? ScriptEngineMajorVersion() //IE11 detection
232
+ : new Function("/*@cc_on return @_jscript_version; @*/")() >= 10, //conditional compilation from mickeysoft trick
233
+ ua = navigator.userAgent,
234
+ iphone = ua.match(new RegExp("iphone", "i")) !== null,
235
+ android = ua.match(new RegExp("android.*safari.*", "i")) !== null,
236
+ androidchrome = ua.match(new RegExp("android.*chrome.*", "i")) !== null,
237
+ androidfirefox = ua.match(new RegExp("android.*firefox.*", "i")) !== null,
238
+ kindle = /Kindle/i.test(ua) || /Silk/i.test(ua) || /KFTT/i.test(ua) || /KFOT/i.test(ua) || /KFJWA/i.test(ua) || /KFJWI/i.test(ua) || /KFSOWI/i.test(ua) || /KFTHWA/i.test(ua) || /KFTHWI/i.test(ua) || /KFAPWA/i.test(ua) || /KFAPWI/i.test(ua),
239
+ PasteEventType = isInputEventSupported('paste') ? 'paste' : isInputEventSupported('input') ? 'input' : "propertychange";
240
+
241
+ //if (androidchrome) {
242
+ // var browser = navigator.userAgent.match(new RegExp("chrome.*", "i")),
243
+ // version = parseInt(new RegExp(/[0-9]+/).exec(browser));
244
+ // androidchrome32 = (version == 32);
245
+ //}
246
+
247
+ //masking scope
248
+ //actionObj definition see below
249
+ function maskScope(actionObj, maskset, opts) {
250
+ var isRTL = false,
251
+ valueOnFocus,
252
+ $el,
253
+ skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround
254
+ skipInputEvent = false, //skip when triggered from within inputmask
255
+ ignorable = false,
256
+ maxLength;
257
+
258
+ //maskset helperfunctions
259
+
260
+
261
+ function getMaskTemplate(baseOnInput, minimalPos, includeInput) {
262
+ minimalPos = minimalPos || 0;
263
+ var maskTemplate = [], ndxIntlzr, pos = 0, test, testPos;
264
+ do {
265
+ if (baseOnInput === true && getMaskSet()['validPositions'][pos]) {
266
+ var validPos = getMaskSet()['validPositions'][pos];
267
+ test = validPos["match"];
268
+ ndxIntlzr = validPos["locator"].slice();
269
+ maskTemplate.push(test["fn"] == null ? test["def"] : (includeInput === true ? validPos["input"] : opts.placeholder.charAt(pos % opts.placeholder.length)));
270
+ } else {
271
+ if (minimalPos > pos) {
272
+ var testPositions = getTests(pos, ndxIntlzr, pos - 1);
273
+ testPos = testPositions[0];
274
+ } else {
275
+ testPos = getTestTemplate(pos, ndxIntlzr, pos - 1);
276
+ }
277
+ test = testPos["match"];
278
+ ndxIntlzr = testPos["locator"].slice();
279
+ maskTemplate.push(test["fn"] == null ? test["def"] : opts.placeholder.charAt(pos % opts.placeholder.length));
280
+ }
281
+ pos++;
282
+ } while ((maxLength == undefined || pos - 1 < maxLength) && test["fn"] != null || (test["fn"] == null && test["def"] != "") || minimalPos >= pos);
283
+ maskTemplate.pop(); //drop the last one which is empty
284
+ return maskTemplate;
285
+ }
286
+
287
+ function getMaskSet() {
288
+ return maskset;
289
+ }
290
+
291
+ function resetMaskSet(soft) {
292
+ var maskset = getMaskSet();
293
+ maskset["buffer"] = undefined;
294
+ maskset["tests"] = {};
295
+ if (soft !== true) {
296
+ maskset["_buffer"] = undefined;
297
+ maskset["validPositions"] = {};
298
+ maskset["p"] = -1;
299
+ }
300
+ }
301
+
302
+ function getLastValidPosition(closestTo) {
303
+ var maskset = getMaskSet(), lastValidPosition = -1, valids = maskset["validPositions"];
304
+ if ($.isFunction(opts.getLastValidPosition))
305
+ lastValidPosition = opts.getLastValidPosition.call($el, maskset, closestTo, opts);
306
+ else {
307
+ if (closestTo == undefined) closestTo = -1;
308
+ var before = lastValidPosition, after = lastValidPosition;
309
+ for (var posNdx in valids) {
310
+ var psNdx = parseInt(posNdx);
311
+ if (closestTo == -1 || valids[psNdx]["match"].fn != null) {
312
+ if (psNdx < closestTo) before = psNdx;
313
+ if (psNdx >= closestTo) after = psNdx;
314
+ }
315
+ }
316
+ lastValidPosition = (closestTo - before) > 1 || after < closestTo ? before : after;
317
+ }
318
+ return lastValidPosition;
319
+ }
320
+
321
+ function setValidPosition(pos, validTest, fromSetValid) {
322
+ if (opts.insertMode && getMaskSet()["validPositions"][pos] != undefined && fromSetValid == undefined) {
323
+ //reposition & revalidate others
324
+ var positionsClone = $.extend(true, {}, getMaskSet()["validPositions"]), lvp = getLastValidPosition(), i;
325
+ for (i = pos; i <= lvp; i++) { //clear selection
326
+ delete getMaskSet()["validPositions"][i];
327
+ }
328
+ getMaskSet()["validPositions"][pos] = validTest;
329
+ var valid = true;
330
+ for (i = pos; i <= lvp ; i++) {
331
+ var t = positionsClone[i];
332
+ if (t != undefined) {
333
+ var j = t["match"].fn == null ? i + 1 : seekNext(i);
334
+ if (positionCanMatchDefinition(j, t["match"].def)) {
335
+ valid = valid && isValid(j, t["input"], true, true) !== false;
336
+ } else valid = false;
337
+ }
338
+ if (!valid) break;
339
+ }
340
+
341
+ if (!valid) {
342
+ getMaskSet()["validPositions"] = $.extend(true, {}, positionsClone);
343
+ return false;
344
+ }
345
+ } else
346
+ getMaskSet()["validPositions"][pos] = validTest;
347
+
348
+ return true;
349
+ }
350
+
351
+ function stripValidPositions(start, end) {
352
+ var i, startPos = start, lvp;
353
+ for (i = start; i < end; i++) { //clear selection
354
+ delete getMaskSet()["validPositions"][i];
355
+ }
356
+
357
+ for (i = end ; i <= getLastValidPosition() ;) {
358
+ var t = getMaskSet()["validPositions"][i];
359
+ var s = getMaskSet()["validPositions"][startPos];
360
+ if (t != undefined && s == undefined) {
361
+ if (positionCanMatchDefinition(startPos, t.match.def) && isValid(startPos, t["input"], true) !== false) {
362
+ delete getMaskSet()["validPositions"][i];
363
+ i++;
364
+ }
365
+ startPos++;
366
+ } else i++;
367
+ }
368
+ lvp = getLastValidPosition();
369
+ //catchup
370
+ while (lvp > 0 && (getMaskSet()["validPositions"][lvp] == undefined || getMaskSet()["validPositions"][lvp].match.fn == null)) {
371
+ delete getMaskSet()["validPositions"][lvp];
372
+ lvp--;
373
+ }
374
+ resetMaskSet(true);
375
+ }
376
+
377
+ function getTestTemplate(pos, ndxIntlzr, tstPs) {
378
+ var testPositions = getTests(pos, ndxIntlzr, tstPs), testPos;
379
+ for (var ndx = 0; ndx < testPositions.length; ndx++) {
380
+ testPos = testPositions[ndx];
381
+ if (opts.greedy || (testPos["match"] && (testPos["match"].optionality === false || testPos["match"].newBlockMarker === false) && testPos["match"].optionalQuantifier !== true)) {
382
+ break;
383
+ }
384
+ }
385
+
386
+ return testPos;
387
+ }
388
+ function getTest(pos) {
389
+ if (getMaskSet()['validPositions'][pos]) {
390
+ return getMaskSet()['validPositions'][pos]["match"];
391
+ }
392
+ return getTests(pos)[0]["match"];
393
+ }
394
+ function positionCanMatchDefinition(pos, def) {
395
+ var valid = false, tests = getTests(pos);
396
+ for (var tndx = 0; tndx < tests.length; tndx++) {
397
+ if (tests[tndx]["match"] && tests[tndx]["match"].def == def) {
398
+ valid = true;
399
+ break;
400
+ }
401
+ }
402
+ return valid;
403
+ };
404
+ function getTests(pos, ndxIntlzr, tstPs) {
405
+ var maskTokens = getMaskSet()["maskToken"], testPos = ndxIntlzr ? tstPs : 0, ndxInitializer = ndxIntlzr || [0], matches = [], insertStop = false;
406
+
407
+ function ResolveTestFromToken(maskToken, ndxInitializer, loopNdx, quantifierRecurse) { //ndxInitilizer contains a set of indexes to speedup searches in the mtokens
408
+
409
+ function handleMatch(match, loopNdx, quantifierRecurse) {
410
+ if (testPos == pos && match.matches == undefined) {
411
+ matches.push({ "match": match, "locator": loopNdx.reverse() });
412
+ return true;
413
+ } else if (match.matches != undefined) {
414
+ if (match.isGroup && quantifierRecurse !== true) { //when a group pass along to the quantifier
415
+ match = handleMatch(maskToken.matches[tndx + 1], loopNdx);
416
+ if (match) return true;
417
+ } else if (match.isOptional) {
418
+ var optionalToken = match;
419
+ match = ResolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse);
420
+ if (match) {
421
+ var latestMatch = matches[matches.length - 1]["match"];
422
+ var isFirstMatch = $.inArray(latestMatch, optionalToken.matches) == 0;
423
+ if (isFirstMatch) {
424
+ insertStop = true; //insert a stop for non greedy
425
+ }
426
+ testPos = pos; //match the position after the group
427
+ }
428
+ } else if (match.isAlternator) {
429
+ //TODO
430
+ } else if (match.isQuantifier && quantifierRecurse !== true) {
431
+ var qt = match;
432
+ opts.greedy = opts.greedy && isFinite(qt.quantifier.max); //greedy must be off when * or + is used (always!!)
433
+ for (var qndx = (ndxInitializer.length > 0 && quantifierRecurse !== true) ? ndxInitializer.shift() : 0; (qndx < (isNaN(qt.quantifier.max) ? qndx + 1 : qt.quantifier.max)) && testPos <= pos; qndx++) {
434
+ var tokenGroup = maskToken.matches[$.inArray(qt, maskToken.matches) - 1];
435
+ match = handleMatch(tokenGroup, [qndx].concat(loopNdx), true);
436
+ if (match) {
437
+ //get latest match
438
+ var latestMatch = matches[matches.length - 1]["match"];
439
+ latestMatch.optionalQuantifier = qndx > qt.quantifier.min - 1;
440
+ var isFirstMatch = $.inArray(latestMatch, tokenGroup.matches) == 0;
441
+ if (isFirstMatch) { //search for next possible match
442
+ if (qndx > qt.quantifier.min - 1) {
443
+ insertStop = true;
444
+ testPos = pos; //match the position after the group
445
+ break; //stop quantifierloop
446
+ } else return true;
447
+ } else {
448
+ return true;
449
+ }
450
+ }
451
+ }
452
+ } else {
453
+ match = ResolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse);
454
+ if (match)
455
+ return true;
456
+ }
457
+ } else testPos++;
458
+ }
459
+
460
+ for (var tndx = (ndxInitializer.length > 0 ? ndxInitializer.shift() : 0) ; tndx < maskToken.matches.length; tndx++) {
461
+ if (maskToken.matches[tndx]["isQuantifier"] !== true) {
462
+ var match = handleMatch(maskToken.matches[tndx], [tndx].concat(loopNdx), quantifierRecurse);
463
+ if (match && testPos == pos) {
464
+ return match;
465
+ } else if (testPos > pos) {
466
+ break;
467
+ }
468
+ }
469
+ }
470
+ }
471
+
472
+ //if (disableCache !== true && getMaskSet()['tests'][pos] && !getMaskSet()['validPositions'][pos]) {
473
+ // return getMaskSet()['tests'][pos];
474
+ //}
475
+ if (ndxIntlzr == undefined) {
476
+ var previousPos = pos - 1, test;
477
+ while ((test = getMaskSet()['validPositions'][previousPos]) == undefined && previousPos > -1) {
478
+ previousPos--;
479
+ }
480
+ if (test != undefined && previousPos > -1) {
481
+ testPos = previousPos;
482
+ ndxInitializer = test["locator"].slice();
483
+ } else {
484
+ previousPos = pos - 1;
485
+ while ((test = getMaskSet()['tests'][previousPos]) == undefined && previousPos > -1) {
486
+ previousPos--;
487
+ }
488
+ if (test != undefined && previousPos > -1) {
489
+ testPos = previousPos;
490
+ ndxInitializer = test[0]["locator"].slice();
491
+ }
492
+ }
493
+ }
494
+ for (var mtndx = ndxInitializer.shift() ; mtndx < maskTokens.length; mtndx++) {
495
+ var match = ResolveTestFromToken(maskTokens[mtndx], ndxInitializer, [mtndx]);
496
+ if ((match && testPos == pos) || testPos > pos) {
497
+ break;
498
+ }
499
+ }
500
+ if (matches.length == 0 || insertStop)
501
+ matches.push({ "match": { fn: null, cardinality: 0, optionality: true, casing: null, def: "" }, "locator": [] });
502
+
503
+ getMaskSet()['tests'][pos] = matches;
504
+ //console.log(pos + " - " + JSON.stringify(matches));
505
+ return matches;
506
+ }
507
+
508
+ function getBufferTemplate() {
509
+ if (getMaskSet()['_buffer'] == undefined) {
510
+ //generate template
511
+ getMaskSet()["_buffer"] = getMaskTemplate(false, 1);
512
+ }
513
+ return getMaskSet()['_buffer'];
514
+ }
515
+
516
+ function getBuffer() {
517
+ if (getMaskSet()['buffer'] == undefined) {
518
+ getMaskSet()['buffer'] = getMaskTemplate(true, getLastValidPosition(), true);
519
+ }
520
+ return getMaskSet()['buffer'];
521
+ }
522
+
523
+ function refreshFromBuffer(start, end) {
524
+ var buffer = getBuffer().slice(); //work on clone
525
+ for (var i = start; i < end; i++) {
526
+ if (buffer[i] != getPlaceholder(i) && buffer[i] != opts.skipOptionalPartCharacter) {
527
+ isValid(i, buffer[i], true, true);
528
+ }
529
+ }
530
+ }
531
+
532
+ function casing(elem, test) {
533
+ switch (test.casing) {
534
+ case "upper":
535
+ elem = elem.toUpperCase();
536
+ break;
537
+ case "lower":
538
+ elem = elem.toLowerCase();
539
+ break;
540
+ }
541
+
542
+ return elem;
543
+ }
544
+
545
+ function isValid(pos, c, strict, fromSetValid) { //strict true ~ no correction or autofill
546
+ strict = strict === true; //always set a value to strict to prevent possible strange behavior in the extensions
547
+
548
+ function _isValid(position, c, strict, fromSetValid) {
549
+
550
+ var rslt = false;
551
+ $.each(getTests(position), function (ndx, tst) {
552
+ var test = tst["match"];
553
+ var loopend = c ? 1 : 0, chrs = '', buffer = getBuffer();
554
+ for (var i = test.cardinality; i > loopend; i--) {
555
+ chrs += getBufferElement(position - (i - 1));
556
+ }
557
+ if (c) {
558
+ chrs += c;
559
+ }
560
+
561
+ //return is false or a json object => { pos: ??, c: ??} or true
562
+ rslt = test.fn != null ?
563
+ test.fn.test(chrs, buffer, position, strict, opts)
564
+ : (c == test["def"] || c == opts.skipOptionalPartCharacter) && test["def"] != "" ? //non mask
565
+ { c: test["def"], pos: position }
566
+ : false;
567
+
568
+ if (rslt !== false) {
569
+ var elem = rslt.c != undefined ? rslt.c : c;
570
+ elem = (elem == opts.skipOptionalPartCharacter && test["fn"] === null) ? test["def"] : elem;
571
+
572
+ var validatedPos = position;
573
+ if (rslt["refreshFromBuffer"]) {
574
+ var refresh = rslt["refreshFromBuffer"];
575
+ strict = true;
576
+ if (refresh === true) {
577
+ getMaskSet()["validPositions"] = {};
578
+ getMaskSet()["tests"] = {};
579
+ refreshFromBuffer(0, getBuffer().length);
580
+ }
581
+ else {
582
+ refreshFromBuffer(refresh["start"], refresh["end"]);
583
+ }
584
+ if (rslt.pos == undefined && rslt.c == undefined) {
585
+ rslt.pos = getLastValidPosition();
586
+ return false;//breakout if refreshFromBuffer && nothing to insert
587
+ }
588
+ validatedPos = rslt.pos != undefined ? rslt.pos : position;
589
+ tst = getTests(validatedPos)[0]; //possible mismatch TODO
590
+
591
+ } else if (rslt !== true && rslt["pos"] != position) { //their is a position offset
592
+ validatedPos = rslt["pos"];
593
+ refreshFromBuffer(position, validatedPos);
594
+ tst = getTests(validatedPos)[0]; //possible mismatch TODO
595
+ }
596
+ if (ndx > 0) {
597
+ resetMaskSet(true);
598
+ }
599
+ if (!setValidPosition(validatedPos, $.extend({}, tst, { "input": casing(elem, test) }), fromSetValid))
600
+ rslt = false;
601
+ return false; //break from $.each
602
+ }
603
+ });
604
+
605
+ return rslt;
606
+ }
607
+
608
+ var maskPos = pos;
609
+ var result = _isValid(maskPos, c, strict, fromSetValid);
610
+ if (!strict && result === false) {
611
+ var currentPosValid = getMaskSet()["validPositions"][maskPos];
612
+ if (currentPosValid && currentPosValid["match"].fn == null && (currentPosValid["match"].def == c || c == opts.skipOptionalPartCharacter)) {
613
+ result = { "caret": seekNext(maskPos) };
614
+ } else if ((opts.insertMode || getMaskSet()["validPositions"][seekNext(maskPos)] == undefined) && !isMask(maskPos)) { //does the input match on a further position?
615
+ for (var nPos = maskPos + 1, snPos = seekNext(maskPos) ; nPos <= snPos; nPos++) {
616
+ result = _isValid(nPos, c, strict, fromSetValid);
617
+ if (result !== false) {
618
+ maskPos = nPos;
619
+ break;
620
+ }
621
+ }
622
+ }
623
+ }
624
+
625
+ if (result === true) result = { "pos": maskPos };
626
+ return result;
627
+ }
628
+
629
+ function isMask(pos) {
630
+ var test = getTest(pos);
631
+ return test.fn != null ? test.fn : false;
632
+ }
633
+
634
+ function getMaskLength() {
635
+ var maskLength;
636
+ maxLength = $el.prop('maxLength');
637
+ if (maxLength == -1) maxLength = undefined; /* FF sets no defined max length to -1 */
638
+ if (opts.greedy == false) {
639
+ var pos, lvp = getLastValidPosition(), testPos = getMaskSet()["validPositions"][lvp],
640
+ ndxIntlzr = testPos != undefined ? testPos["locator"].slice() : undefined;
641
+ for (pos = lvp + 1; testPos == undefined || (testPos["match"]["fn"] != null || (testPos["match"]["fn"] == null && testPos["match"]["def"] != "")) ; pos++) {
642
+ testPos = getTestTemplate(pos, ndxIntlzr, pos - 1);
643
+ ndxIntlzr = testPos["locator"].slice();
644
+ }
645
+ maskLength = pos;
646
+ } else
647
+ maskLength = getBuffer().length;
648
+
649
+ return (maxLength == undefined || maskLength < maxLength) ? maskLength : maxLength;
650
+ }
651
+
652
+ function seekNext(pos) {
653
+ var maskL = getMaskLength();
654
+ if (pos >= maskL) return maskL;
655
+ var position = pos;
656
+ while (++position < maskL && !isMask(position) && (opts.nojumps !== true || opts.nojumpsThreshold > position)) {
657
+ }
658
+ return position;
659
+ }
660
+
661
+ function seekPrevious(pos) {
662
+ var position = pos;
663
+ if (position <= 0) return 0;
664
+
665
+ while (--position > 0 && !isMask(position)) {
666
+ };
667
+ return position;
668
+ }
669
+
670
+ function getBufferElement(position) {
671
+ return getMaskSet()["validPositions"][position] == undefined ? getPlaceholder(position) : getMaskSet()["validPositions"][position]["input"];
672
+ }
673
+
674
+ function writeBuffer(input, buffer, caretPos) {
675
+ input._valueSet(buffer.join(''));
676
+ if (caretPos != undefined) {
677
+ caret(input, caretPos);
678
+ }
679
+ }
680
+
681
+ function getPlaceholder(pos, test) {
682
+ test = test || getTest(pos);
683
+ return test["fn"] == null ? test["def"] : opts.placeholder.charAt(pos % opts.placeholder.length);
684
+ }
685
+
686
+ function checkVal(input, writeOut, strict, nptvl, intelliCheck) {
687
+ var inputValue = nptvl != undefined ? nptvl.slice() : truncateInput(input._valueGet()).split('');
688
+ resetMaskSet();
689
+ if (writeOut) input._valueSet(""); //initial clear
690
+ $.each(inputValue, function (ndx, charCode) {
691
+ if (intelliCheck === true) {
692
+ var p = getMaskSet()["p"],
693
+ lvp = p == -1 ? p : seekPrevious(p),
694
+ pos = lvp == -1 ? ndx : seekNext(lvp);
695
+ if ($.inArray(charCode, getBufferTemplate().slice(lvp + 1, pos)) == -1) {
696
+ keypressEvent.call(input, undefined, true, charCode.charCodeAt(0), false, strict, ndx);
697
+ }
698
+ } else {
699
+ keypressEvent.call(input, undefined, true, charCode.charCodeAt(0), false, strict, ndx);
700
+ strict = strict || (ndx > 0 && ndx > getMaskSet()["p"]);
701
+ }
702
+ });
703
+ if (writeOut)
704
+ writeBuffer(input, getBuffer(), $(input).is(":focus") ? seekNext(getLastValidPosition(0)) : undefined);
705
+ }
706
+
707
+ function escapeRegex(str) {
708
+ return $.inputmask.escapeRegex.call(this, str);
709
+ }
710
+
711
+ function truncateInput(inputValue) {
712
+ return inputValue.replace(new RegExp("(" + escapeRegex(getBufferTemplate().join('')) + ")*$"), "");
713
+ }
714
+
715
+ function clearOptionalTail(input) {
716
+ var buffer = getBuffer(), tmpBuffer = buffer.slice(),
717
+ pos, lvp = getLastValidPosition(), positions = {},
718
+ ndxIntlzr = getMaskSet()["validPositions"][lvp] != undefined ? getMaskSet()["validPositions"][lvp]["locator"].slice() : undefined, testPos;
719
+ for (pos = lvp + 1; pos < tmpBuffer.length; pos++) {
720
+ testPos = getTestTemplate(pos, ndxIntlzr, pos - 1);
721
+ ndxIntlzr = testPos["locator"].slice();
722
+ positions[pos] = testPos;
723
+ }
724
+
725
+ for (pos = tmpBuffer.length - 1; pos > lvp; pos--) {
726
+ testPos = positions[pos]["match"];
727
+ if (testPos.optionality && tmpBuffer[pos] == getPlaceholder(pos, testPos)) {
728
+ tmpBuffer.pop();
729
+ } else break;
730
+ }
731
+ writeBuffer(input, tmpBuffer);
732
+ }
733
+
734
+ function unmaskedvalue($input, skipDatepickerCheck) {
735
+ if ($input.data('_inputmask') && (skipDatepickerCheck === true || !$input.hasClass('hasDatepicker'))) {
736
+ var umValue = [], vps = getMaskSet()["validPositions"];
737
+ for (var pndx in vps) {
738
+ if (vps[pndx]["match"] && vps[pndx]["match"].fn != null) {
739
+ umValue.push(vps[pndx]["input"]);
740
+ }
741
+ }
742
+ var unmaskedValue = (isRTL ? umValue.reverse() : umValue).join('');
743
+ var bufferValue = (isRTL ? getBuffer().reverse() : getBuffer()).join('');
744
+ return $.isFunction(opts.onUnMask) ? opts.onUnMask.call($input, bufferValue, unmaskedValue, opts) : unmaskedValue;
745
+ } else {
746
+ return $input[0]._valueGet();
747
+ }
748
+ }
749
+
750
+ function TranslatePosition(pos) {
751
+ if (isRTL && typeof pos == 'number' && (!opts.greedy || opts.placeholder != "")) {
752
+ var bffrLght = getBuffer().length;
753
+ pos = bffrLght - pos;
754
+ }
755
+ return pos;
756
+ }
757
+
758
+ function caret(input, begin, end) {
759
+ var npt = input.jquery && input.length > 0 ? input[0] : input, range;
760
+ if (typeof begin == 'number') {
761
+ begin = TranslatePosition(begin);
762
+ end = TranslatePosition(end);
763
+ end = (typeof end == 'number') ? end : begin;
764
+
765
+ //store caret for multi scope
766
+ var data = $(npt).data('_inputmask') || {};
767
+ data["caret"] = { "begin": begin, "end": end };
768
+ $(npt).data('_inputmask', data);
769
+
770
+ if (!$(npt).is(":visible")) {
771
+ return;
772
+ }
773
+
774
+ npt.scrollLeft = npt.scrollWidth;
775
+ if (opts.insertMode == false && begin == end) end++; //set visualization for insert/overwrite mode
776
+ if (npt.setSelectionRange) {
777
+ npt.selectionStart = begin;
778
+ npt.selectionEnd = end;
779
+
780
+ } else if (npt.createTextRange) {
781
+ range = npt.createTextRange();
782
+ range.collapse(true);
783
+ range.moveEnd('character', end);
784
+ range.moveStart('character', begin);
785
+ range.select();
786
+ }
787
+ } else {
788
+ var data = $(npt).data('_inputmask');
789
+ if (!$(npt).is(":visible") && data && data["caret"] != undefined) {
790
+ begin = data["caret"]["begin"];
791
+ end = data["caret"]["end"];
792
+ } else if (npt.setSelectionRange) {
793
+ begin = npt.selectionStart;
794
+ end = npt.selectionEnd;
795
+ } else if (document.selection && document.selection.createRange) {
796
+ range = document.selection.createRange();
797
+ begin = 0 - range.duplicate().moveStart('character', -100000);
798
+ end = begin + range.text.length;
799
+ }
800
+ begin = TranslatePosition(begin);
801
+ end = TranslatePosition(end);
802
+ return { "begin": begin, "end": end };
803
+ }
804
+ }
805
+
806
+ function isComplete(buffer) { //return true / false / undefined (repeat *)
807
+ if ($.isFunction(opts.isComplete)) return opts.isComplete.call($el, buffer, opts);
808
+ if (opts.repeat == "*") return undefined;
809
+ var complete = false,
810
+ aml = seekPrevious(getMaskLength());
811
+ if (getLastValidPosition() == aml) {
812
+ complete = true;
813
+ for (var i = 0; i <= aml; i++) {
814
+ var mask = isMask(i);
815
+ if ((mask && (buffer[i] == undefined || buffer[i] == getPlaceholder(i))) || (!mask && buffer[i] != getPlaceholder(i))) {
816
+ complete = false;
817
+ break;
818
+ }
819
+ }
820
+ }
821
+ return complete;
822
+ }
823
+
824
+ function isSelection(begin, end) {
825
+ return isRTL ? (begin - end) > 1 || ((begin - end) == 1 && opts.insertMode) :
826
+ (end - begin) > 1 || ((end - begin) == 1 && opts.insertMode);
827
+ }
828
+
829
+ function installEventRuler(npt) {
830
+ var events = $._data(npt).events;
831
+
832
+ $.each(events, function (eventType, eventHandlers) {
833
+ $.each(eventHandlers, function (ndx, eventHandler) {
834
+ if (eventHandler.namespace == "inputmask") {
835
+ if (eventHandler.type != "setvalue") {
836
+ var handler = eventHandler.handler;
837
+ eventHandler.handler = function (e) {
838
+ if (this.readOnly || this.disabled)
839
+ e.preventDefault;
840
+ else
841
+ return handler.apply(this, arguments);
842
+ };
843
+ }
844
+ }
845
+ });
846
+ });
847
+ }
848
+
849
+ function patchValueProperty(npt) {
850
+
851
+ function PatchValhook(type) {
852
+ if ($.valHooks[type] == undefined || $.valHooks[type].inputmaskpatch != true) {
853
+ var valueGet = $.valHooks[type] && $.valHooks[type].get ? $.valHooks[type].get : function (elem) { return elem.value; };
854
+ var valueSet = $.valHooks[type] && $.valHooks[type].set ? $.valHooks[type].set : function (elem, value) {
855
+ elem.value = value;
856
+ return elem;
857
+ };
858
+
859
+ $.valHooks[type] = {
860
+ get: function (elem) {
861
+ var $elem = $(elem);
862
+ if ($elem.data('_inputmask')) {
863
+ if ($elem.data('_inputmask')['opts'].autoUnmask)
864
+ return $elem.inputmask('unmaskedvalue');
865
+ else {
866
+ var result = valueGet(elem),
867
+ inputData = $elem.data('_inputmask'),
868
+ maskset = inputData['maskset'],
869
+ bufferTemplate = maskset['_buffer'];
870
+ bufferTemplate = bufferTemplate ? bufferTemplate.join('') : '';
871
+ return result != bufferTemplate ? result : '';
872
+ }
873
+ } else return valueGet(elem);
874
+ },
875
+ set: function (elem, value) {
876
+ var $elem = $(elem);
877
+ var result = valueSet(elem, value);
878
+ if ($elem.data('_inputmask')) $elem.triggerHandler('setvalue.inputmask');
879
+ return result;
880
+ },
881
+ inputmaskpatch: true
882
+ };
883
+ }
884
+ }
885
+
886
+ var valueProperty;
887
+ if (Object.getOwnPropertyDescriptor)
888
+ valueProperty = Object.getOwnPropertyDescriptor(npt, "value");
889
+ if (valueProperty && valueProperty.get) {
890
+ if (!npt._valueGet) {
891
+ var valueGet = valueProperty.get;
892
+ var valueSet = valueProperty.set;
893
+ npt._valueGet = function () {
894
+ return isRTL ? valueGet.call(this).split('').reverse().join('') : valueGet.call(this);
895
+ };
896
+ npt._valueSet = function (value) {
897
+ valueSet.call(this, isRTL ? value.split('').reverse().join('') : value);
898
+ };
899
+
900
+ Object.defineProperty(npt, "value", {
901
+ get: function () {
902
+ var $self = $(this), inputData = $(this).data('_inputmask');
903
+ if (inputData) {
904
+ return inputData['opts'].autoUnmask ? $self.inputmask('unmaskedvalue') : (valueGet.call(this) != getBufferTemplate().join('') ? valueGet.call(this) : '');
905
+ } else return valueGet.call(this);
906
+ },
907
+ set: function (value) {
908
+ valueSet.call(this, value);
909
+ $(this).triggerHandler('setvalue.inputmask');
910
+ }
911
+ });
912
+ }
913
+ } else if (document.__lookupGetter__ && npt.__lookupGetter__("value")) {
914
+ if (!npt._valueGet) {
915
+ var valueGet = npt.__lookupGetter__("value");
916
+ var valueSet = npt.__lookupSetter__("value");
917
+ npt._valueGet = function () {
918
+ return isRTL ? valueGet.call(this).split('').reverse().join('') : valueGet.call(this);
919
+ };
920
+ npt._valueSet = function (value) {
921
+ valueSet.call(this, isRTL ? value.split('').reverse().join('') : value);
922
+ };
923
+
924
+ npt.__defineGetter__("value", function () {
925
+ var $self = $(this), inputData = $(this).data('_inputmask');
926
+ if (inputData) {
927
+ return inputData['opts'].autoUnmask ? $self.inputmask('unmaskedvalue') : (valueGet.call(this) != getBufferTemplate().join('') ? valueGet.call(this) : '');
928
+ } else return valueGet.call(this);
929
+ });
930
+ npt.__defineSetter__("value", function (value) {
931
+ valueSet.call(this, value);
932
+ $(this).triggerHandler('setvalue.inputmask');
933
+ });
934
+ }
935
+ } else {
936
+ if (!npt._valueGet) {
937
+ npt._valueGet = function () { return isRTL ? this.value.split('').reverse().join('') : this.value; };
938
+ npt._valueSet = function (value) { this.value = isRTL ? value.split('').reverse().join('') : value; };
939
+ }
940
+ PatchValhook(npt.type);
941
+ }
942
+ }
943
+
944
+ function HandleRemove(input, k, pos) {
945
+ if (opts.numericInput || isRTL) {
946
+ switch (k) {
947
+ case opts.keyCode.BACKSPACE:
948
+ k = opts.keyCode.DELETE;
949
+ break;
950
+ case opts.keyCode.DELETE:
951
+ k = opts.keyCode.BACKSPACE;
952
+ break;
953
+ }
954
+ if (isRTL) {
955
+ var pend = pos.end;
956
+ pos.end = pos.begin;
957
+ pos.begin = pend;
958
+ }
959
+ }
960
+
961
+ if (pos.begin == pos.end) {
962
+ var posBegin = k == opts.keyCode.BACKSPACE ? pos.begin - 1 : pos.begin;
963
+ if (k == opts.keyCode.BACKSPACE)
964
+ pos.begin = seekPrevious(pos.begin);
965
+ else if (k == opts.keyCode.DELETE)
966
+ pos.end++;
967
+ } else if (pos.end - pos.begin == 1 && !opts.insertMode) {
968
+ if (k == opts.keyCode.BACKSPACE)
969
+ pos.begin--;
970
+ }
971
+
972
+ stripValidPositions(pos.begin, pos.end);
973
+ var firstMaskPos = seekNext(-1);
974
+ if (getLastValidPosition() < firstMaskPos) {
975
+ getMaskSet()["p"] = firstMaskPos;
976
+ } else {
977
+ getMaskSet()["p"] = pos.begin;
978
+ }
979
+ }
980
+
981
+ function keydownEvent(e) {
982
+ //Safari 5.1.x - modal dialog fires keypress twice workaround
983
+ skipKeyPressEvent = false;
984
+ var input = this, $input = $(input), k = e.keyCode, pos = caret(input);
985
+
986
+ //backspace, delete, and escape get special treatment
987
+ if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127) || e.ctrlKey && k == 88) { //backspace/delete
988
+ e.preventDefault(); //stop default action but allow propagation
989
+ if (k == 88) valueOnFocus = getBuffer().join('');
990
+ HandleRemove(input, k, pos);
991
+ writeBuffer(input, getBuffer(), getMaskSet()["p"]);
992
+ if (input._valueGet() == getBufferTemplate().join(''))
993
+ $input.trigger('cleared');
994
+
995
+ if (opts.showTooltip) { //update tooltip
996
+ $input.prop("title", getMaskSet()["mask"]);
997
+ }
998
+ } else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch
999
+ setTimeout(function () {
1000
+ var caretPos = seekNext(getLastValidPosition());
1001
+ if (!opts.insertMode && caretPos == getMaskLength() && !e.shiftKey) caretPos--;
1002
+ caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
1003
+ }, 0);
1004
+ } else if ((k == opts.keyCode.HOME && !e.shiftKey) || k == opts.keyCode.PAGE_UP) { //Home or page_up
1005
+ caret(input, 0, e.shiftKey ? pos.begin : 0);
1006
+ } else if (k == opts.keyCode.ESCAPE || (k == 90 && e.ctrlKey)) { //escape && undo
1007
+ checkVal(input, true, false, valueOnFocus.split(''));
1008
+ $input.click();
1009
+ } else if (k == opts.keyCode.INSERT && !(e.shiftKey || e.ctrlKey)) { //insert
1010
+ opts.insertMode = !opts.insertMode;
1011
+ caret(input, !opts.insertMode && pos.begin == getMaskLength() ? pos.begin - 1 : pos.begin);
1012
+ } else if (opts.insertMode == false && !e.shiftKey) {
1013
+ if (k == opts.keyCode.RIGHT) {
1014
+ setTimeout(function () {
1015
+ var caretPos = caret(input);
1016
+ caret(input, caretPos.begin);
1017
+ }, 0);
1018
+ } else if (k == opts.keyCode.LEFT) {
1019
+ setTimeout(function () {
1020
+ var caretPos = caret(input);
1021
+ caret(input, caretPos.begin - 1);
1022
+ }, 0);
1023
+ }
1024
+ }
1025
+
1026
+ var currentCaretPos = caret(input);
1027
+ var keydownResult = opts.onKeyDown.call(this, e, getBuffer(), opts);
1028
+ if (keydownResult && keydownResult["refreshFromBuffer"] === true) { //extra stuff to execute on keydown
1029
+ getMaskSet()["validPositions"] = {};
1030
+ getMaskSet()["tests"] = {};
1031
+ refreshFromBuffer(0, getBuffer().length);
1032
+ resetMaskSet(true);
1033
+ writeBuffer(input, getBuffer());
1034
+ caret(input, currentCaretPos.begin, currentCaretPos.end);
1035
+ }
1036
+ ignorable = $.inArray(k, opts.ignorables) != -1;
1037
+ }
1038
+
1039
+ function keypressEvent(e, checkval, k, writeOut, strict, ndx) {
1040
+ //Safari 5.1.x - modal dialog fires keypress twice workaround
1041
+ if (k == undefined && skipKeyPressEvent) return false;
1042
+ skipKeyPressEvent = true;
1043
+
1044
+ var input = this, $input = $(input);
1045
+
1046
+ e = e || window.event;
1047
+ var k = checkval ? k : (e.which || e.charCode || e.keyCode);
1048
+
1049
+ if (checkval !== true && (!(e.ctrlKey && e.altKey) && (e.ctrlKey || e.metaKey || ignorable))) {
1050
+ return true;
1051
+ } else {
1052
+ if (k) {
1053
+ //special treat the decimal separator
1054
+ if (checkval !== true && k == 46 && e.shiftKey == false && opts.radixPoint == ",") k = 44;
1055
+
1056
+ var pos, forwardPosition, c = String.fromCharCode(k);
1057
+ if (checkval) {
1058
+ var pcaret = strict ? ndx : getLastValidPosition() + 1;
1059
+ pos = { begin: pcaret, end: pcaret };
1060
+ } else {
1061
+ pos = caret(input);
1062
+ }
1063
+
1064
+ //should we clear a possible selection??
1065
+ var isSlctn = isSelection(pos.begin, pos.end);
1066
+ if (isSlctn) {
1067
+ getMaskSet()["undoPositions"] = $.extend(true, {}, getMaskSet()["validPositions"]); //init undobuffer for recovery when not valid
1068
+ HandleRemove(input, opts.keyCode.DELETE, pos);
1069
+ if (!opts.insertMode) { //preserve some space
1070
+ opts.insertMode = !opts.insertMode;
1071
+ setValidPosition(pos.begin, strict);
1072
+ opts.insertMode = !opts.insertMode;
1073
+ }
1074
+ isSlctn = !opts.multi;
1075
+ }
1076
+
1077
+ getMaskSet()["writeOutBuffer"] = true;
1078
+ var p = pos.begin;
1079
+ var valResult = isValid(p, c, strict);
1080
+ if (valResult !== false) {
1081
+ if (valResult !== true) {
1082
+ p = valResult.pos != undefined ? valResult.pos : p; //set new position from isValid
1083
+ c = valResult.c != undefined ? valResult.c : c; //set new char from isValid
1084
+ }
1085
+ resetMaskSet(true);
1086
+ if (valResult.caret != undefined)
1087
+ forwardPosition = valResult.caret;
1088
+ else {
1089
+ var vps = getMaskSet()["validPositions"];
1090
+ if (vps[p + 1] != undefined && getTestTemplate(pos + 1, vps[p].locator.slice(), p)["match"].def != vps[p + 1]["match"].def)
1091
+ forwardPosition = p + 1;
1092
+ else forwardPosition = seekNext(p);
1093
+ }
1094
+ getMaskSet()["p"] = forwardPosition; //needed for checkval
1095
+ }
1096
+
1097
+ if (writeOut !== false) {
1098
+ var self = this;
1099
+ setTimeout(function () { opts.onKeyValidation.call(self, valResult, opts); }, 0);
1100
+ if (getMaskSet()["writeOutBuffer"] && valResult !== false) {
1101
+ var buffer = getBuffer();
1102
+ writeBuffer(input, buffer, checkval ? undefined : opts.numericInput ? seekPrevious(forwardPosition) : forwardPosition);
1103
+ if (checkval !== true) {
1104
+ setTimeout(function () { //timeout needed for IE
1105
+ if (isComplete(buffer) === true)
1106
+ $input.trigger("complete");
1107
+ skipInputEvent = true;
1108
+ $input.trigger("input");
1109
+ }, 0);
1110
+ }
1111
+ } else if (isSlctn) {
1112
+ getMaskSet()["buffer"] = undefined;
1113
+ getMaskSet()["validPositions"] = getMaskSet()["undoPositions"];
1114
+ }
1115
+ } else if (isSlctn) {
1116
+ getMaskSet()["buffer"] = undefined;
1117
+ getMaskSet()["validPositions"] = getMaskSet()["undoPositions"];
1118
+ }
1119
+
1120
+
1121
+ if (opts.showTooltip) { //update tooltip
1122
+ $input.prop("title", getMaskSet()["mask"]);
1123
+ }
1124
+
1125
+ //needed for IE8 and below
1126
+ if (e && checkval != true) e.preventDefault ? e.preventDefault() : e.returnValue = false;
1127
+ }
1128
+ }
1129
+ }
1130
+
1131
+ function keyupEvent(e) {
1132
+ var $input = $(this), input = this, k = e.keyCode, buffer = getBuffer();
1133
+
1134
+ var keyupResult = opts.onKeyUp.call(this, e, buffer, opts);
1135
+ if (keyupResult && keyupResult["refreshFromBuffer"] === true) {
1136
+ getMaskSet()["validPositions"] = {};
1137
+ getMaskSet()["tests"] = {};
1138
+ refreshFromBuffer(0, getBuffer().length);
1139
+ resetMaskSet(true);
1140
+ writeBuffer(input, getBuffer());
1141
+ }
1142
+ if (k == opts.keyCode.TAB && opts.showMaskOnFocus) {
1143
+ if ($input.hasClass('focus.inputmask') && input._valueGet().length == 0) {
1144
+ resetMaskSet();
1145
+ buffer = getBuffer();
1146
+ writeBuffer(input, buffer);
1147
+ caret(input, 0);
1148
+ valueOnFocus = getBuffer().join('');
1149
+ } else {
1150
+ writeBuffer(input, buffer);
1151
+ caret(input, TranslatePosition(0), TranslatePosition(getMaskLength()));
1152
+ }
1153
+ }
1154
+ }
1155
+
1156
+ function pasteEvent(e) {
1157
+ if (skipInputEvent === true && e.type == "input") {
1158
+ skipInputEvent = false;
1159
+ return true;
1160
+ }
1161
+
1162
+ var input = this, $input = $(input);
1163
+ //paste event for IE8 and lower I guess ;-)
1164
+ if (e.type == "propertychange" && input._valueGet().length <= getMaskLength()) {
1165
+ return true;
1166
+ }
1167
+ setTimeout(function () {
1168
+ var pasteValue = $.isFunction(opts.onBeforePaste) ? opts.onBeforePaste.call(input, input._valueGet(), opts) : input._valueGet();
1169
+ checkVal(input, true, false, pasteValue.split(''), true);
1170
+ if (isComplete(getBuffer()) === true)
1171
+ $input.trigger("complete");
1172
+ $input.click();
1173
+ }, 0);
1174
+ }
1175
+ function mobileInputEvent(e) {
1176
+ if (skipInputEvent === true && e.type == "input") {
1177
+ skipInputEvent = false;
1178
+ return true;
1179
+ }
1180
+ var input = this;
1181
+
1182
+ //backspace in chrome32 only fires input event - detect & treat
1183
+ var caretPos = caret(input),
1184
+ currentValue = input._valueGet();
1185
+
1186
+ currentValue = currentValue.replace(new RegExp("(" + escapeRegex(getBufferTemplate().join('')) + ")*"), "");
1187
+ //correct caretposition for chrome
1188
+ if (caretPos.begin > currentValue.length) {
1189
+ caret(input, currentValue.length);
1190
+ caretPos = caret(input);
1191
+ }
1192
+ if ((getBuffer().length - currentValue.length) == 1 && currentValue.charAt(caretPos.begin) != getBuffer()[caretPos.begin]
1193
+ && currentValue.charAt(caretPos.begin + 1) != getBuffer()[caretPos.begin]
1194
+ && !isMask(caretPos.begin)) {
1195
+ e.keyCode = opts.keyCode.BACKSPACE;
1196
+ keydownEvent.call(input, e);
1197
+ }
1198
+ e.preventDefault();
1199
+ }
1200
+
1201
+ function mask(el) {
1202
+ $el = $(el);
1203
+ if ($el.is(":input") && $el.attr("type") != "number") {
1204
+ //store tests & original buffer in the input element - used to get the unmasked value
1205
+ $el.data('_inputmask', {
1206
+ 'maskset': maskset,
1207
+ 'opts': opts,
1208
+ 'isRTL': false
1209
+ });
1210
+
1211
+ //show tooltip
1212
+ if (opts.showTooltip) {
1213
+ $el.prop("title", getMaskSet()["mask"]);
1214
+ }
1215
+
1216
+ patchValueProperty(el);
1217
+
1218
+ if (el.dir == "rtl" || opts.rightAlign)
1219
+ $el.css("text-align", "right");
1220
+
1221
+ if (el.dir == "rtl" || opts.numericInput) {
1222
+ el.dir = "ltr";
1223
+ $el.removeAttr("dir");
1224
+ var inputData = $el.data('_inputmask');
1225
+ inputData['isRTL'] = true;
1226
+ $el.data('_inputmask', inputData);
1227
+ isRTL = true;
1228
+ }
1229
+
1230
+ //unbind all events - to make sure that no other mask will interfere when re-masking
1231
+ $el.unbind(".inputmask");
1232
+ $el.removeClass('focus.inputmask');
1233
+ //bind events
1234
+ $el.closest('form').bind("submit", function () { //trigger change on submit if any
1235
+ if (valueOnFocus != getBuffer().join('')) {
1236
+ $el.change();
1237
+ }
1238
+ }).bind('reset', function () {
1239
+ setTimeout(function () {
1240
+ $el.trigger("setvalue");
1241
+ }, 0);
1242
+ });
1243
+ $el.bind("mouseenter.inputmask", function () {
1244
+ var $input = $(this), input = this;
1245
+ if (!$input.hasClass('focus.inputmask') && opts.showMaskOnHover) {
1246
+ if (input._valueGet() != getBuffer().join('')) {
1247
+ writeBuffer(input, getBuffer());
1248
+ }
1249
+ }
1250
+ }).bind("blur.inputmask", function () {
1251
+ var $input = $(this), input = this;
1252
+ if ($input.data('_inputmask')) {
1253
+ var nptValue = input._valueGet(), buffer = getBuffer();
1254
+ $input.removeClass('focus.inputmask');
1255
+ if (valueOnFocus != getBuffer().join('')) {
1256
+ $input.change();
1257
+ }
1258
+ if (opts.clearMaskOnLostFocus && nptValue != '') {
1259
+ if (nptValue == getBufferTemplate().join(''))
1260
+ input._valueSet('');
1261
+ else { //clearout optional tail of the mask
1262
+ clearOptionalTail(input);
1263
+ }
1264
+ }
1265
+ if (isComplete(buffer) === false) {
1266
+ $input.trigger("incomplete");
1267
+ if (opts.clearIncomplete) {
1268
+ resetMaskSet();
1269
+ if (opts.clearMaskOnLostFocus)
1270
+ input._valueSet('');
1271
+ else {
1272
+ buffer = getBufferTemplate().slice();
1273
+ writeBuffer(input, buffer);
1274
+ }
1275
+ }
1276
+ }
1277
+ }
1278
+ }).bind("focus.inputmask", function () {
1279
+ var $input = $(this), input = this, nptValue = input._valueGet();
1280
+ if (opts.showMaskOnFocus && !$input.hasClass('focus.inputmask') && (!opts.showMaskOnHover || (opts.showMaskOnHover && nptValue == ''))) {
1281
+ if (input._valueGet() != getBuffer().join('')) {
1282
+ writeBuffer(input, getBuffer(), seekNext(getLastValidPosition()));
1283
+ }
1284
+ }
1285
+ $input.addClass('focus.inputmask');
1286
+ valueOnFocus = getBuffer().join('');
1287
+ }).bind("mouseleave.inputmask", function () {
1288
+ var $input = $(this), input = this;
1289
+ if (opts.clearMaskOnLostFocus) {
1290
+ if (!$input.hasClass('focus.inputmask') && input._valueGet() != $input.attr("placeholder")) {
1291
+ if (input._valueGet() == getBufferTemplate().join('') || input._valueGet() == '')
1292
+ input._valueSet('');
1293
+ else { //clearout optional tail of the mask
1294
+ clearOptionalTail(input);
1295
+ }
1296
+ }
1297
+ }
1298
+ }).bind("click.inputmask", function () {
1299
+ var input = this;
1300
+ setTimeout(function () {
1301
+ var selectedCaret = caret(input), buffer = getBuffer();
1302
+ if (selectedCaret.begin == selectedCaret.end) {
1303
+ var clickPosition = isRTL ? TranslatePosition(selectedCaret.begin) : selectedCaret.begin,
1304
+ lvp = getLastValidPosition(clickPosition),
1305
+ lastPosition = seekNext(lvp);
1306
+ if (clickPosition < lastPosition) {
1307
+ if (isMask(clickPosition))
1308
+ caret(input, clickPosition);
1309
+ else caret(input, seekNext(clickPosition));
1310
+ } else
1311
+ caret(input, lastPosition);
1312
+ }
1313
+ }, 0);
1314
+ }).bind('dblclick.inputmask', function () {
1315
+ var input = this;
1316
+ setTimeout(function () {
1317
+ caret(input, 0, seekNext(getLastValidPosition()));
1318
+ }, 0);
1319
+ }).bind(PasteEventType + ".inputmask dragdrop.inputmask drop.inputmask", pasteEvent
1320
+ ).bind('setvalue.inputmask', function () {
1321
+ var input = this;
1322
+ checkVal(input, true);
1323
+ valueOnFocus = getBuffer().join('');
1324
+ if (input._valueGet() == getBufferTemplate().join(''))
1325
+ input._valueSet('');
1326
+ }).bind('complete.inputmask', opts.oncomplete
1327
+ ).bind('incomplete.inputmask', opts.onincomplete
1328
+ ).bind('cleared.inputmask', opts.oncleared);
1329
+
1330
+ $el.bind("keydown.inputmask", keydownEvent
1331
+ ).bind("keypress.inputmask", keypressEvent
1332
+ ).bind("keyup.inputmask", keyupEvent);
1333
+
1334
+ if (android || androidfirefox || androidchrome || kindle) {
1335
+ if (PasteEventType == "input") {
1336
+ $el.unbind(PasteEventType + ".inputmask");
1337
+ }
1338
+ $el.bind("input.inputmask", mobileInputEvent);
1339
+ }
1340
+
1341
+ if (msie1x)
1342
+ $el.bind("input.inputmask", pasteEvent);
1343
+
1344
+ //apply mask
1345
+ var initialValue = $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask.call(el, el._valueGet(), opts) : el._valueGet();
1346
+ checkVal(el, true, false, initialValue.split(''), true);
1347
+ valueOnFocus = getBuffer().join('');
1348
+ // Wrap document.activeElement in a try/catch block since IE9 throw "Unspecified error" if document.activeElement is undefined when we are in an IFrame.
1349
+ var activeElement;
1350
+ try {
1351
+ activeElement = document.activeElement;
1352
+ } catch (e) {
1353
+ }
1354
+ if (activeElement === el) { //position the caret when in focus
1355
+ $el.addClass('focus.inputmask');
1356
+ caret(el, seekNext(getLastValidPosition()));
1357
+ } else if (opts.clearMaskOnLostFocus) {
1358
+ if (getBuffer().join('') == getBufferTemplate().join('')) {
1359
+ el._valueSet('');
1360
+ } else {
1361
+ clearOptionalTail(el);
1362
+ }
1363
+ } else {
1364
+ writeBuffer(el, getBuffer());
1365
+ }
1366
+
1367
+ installEventRuler(el);
1368
+ }
1369
+ }
1370
+
1371
+ //action object
1372
+ if (actionObj != undefined) {
1373
+ switch (actionObj["action"]) {
1374
+ case "isComplete":
1375
+ $el = $(actionObj["el"]);
1376
+ maskset = $el.data('_inputmask')['maskset'];
1377
+ opts = $el.data('_inputmask')['opts'];
1378
+ return isComplete(actionObj["buffer"]);
1379
+ case "unmaskedvalue":
1380
+ $el = actionObj["$input"];
1381
+ maskset = $el.data('_inputmask')['maskset'];
1382
+ opts = $el.data('_inputmask')['opts'];
1383
+ isRTL = actionObj["$input"].data('_inputmask')['isRTL'];
1384
+ return unmaskedvalue(actionObj["$input"], actionObj["skipDatepickerCheck"]);
1385
+ case "mask":
1386
+ valueOnFocus = getBuffer().join('');
1387
+ mask(actionObj["el"]);
1388
+ break;
1389
+ case "format":
1390
+ $el = $({});
1391
+ $el.data('_inputmask', {
1392
+ 'maskset': maskset,
1393
+ 'opts': opts,
1394
+ 'isRTL': opts.numericInput
1395
+ });
1396
+ if (opts.numericInput) {
1397
+ isRTL = true;
1398
+ }
1399
+ var valueBuffer = actionObj["value"].split('');
1400
+ checkVal($el, false, false, isRTL ? valueBuffer.reverse() : valueBuffer, true);
1401
+ return isRTL ? getBuffer().reverse().join('') : getBuffer().join('');
1402
+ case "isValid":
1403
+ $el = $({});
1404
+ $el.data('_inputmask', {
1405
+ 'maskset': maskset,
1406
+ 'opts': opts,
1407
+ 'isRTL': opts.numericInput
1408
+ });
1409
+ if (opts.numericInput) {
1410
+ isRTL = true;
1411
+ }
1412
+ var valueBuffer = actionObj["value"].split('');
1413
+ checkVal($el, false, true, isRTL ? valueBuffer.reverse() : valueBuffer);
1414
+ return isComplete(getBuffer());
1415
+ case "getemptymask":
1416
+ $el = $(actionObj["el"]);
1417
+ maskset = $el.data('_inputmask')['maskset'];
1418
+ opts = $el.data('_inputmask')['opts'];
1419
+ return getBufferTemplate();
1420
+ case "remove":
1421
+ var el = actionObj["el"];
1422
+ $el = $(el);
1423
+ maskset = $el.data('_inputmask')['maskset'];
1424
+ opts = $el.data('_inputmask')['opts'];
1425
+ //writeout the unmaskedvalue
1426
+ el._valueSet(unmaskedvalue($el));
1427
+ //unbind all events
1428
+ $el.unbind(".inputmask");
1429
+ $el.removeClass('focus.inputmask');
1430
+ //clear data
1431
+ $el.removeData('_inputmask');
1432
+ //restore the value property
1433
+ var valueProperty;
1434
+ if (Object.getOwnPropertyDescriptor)
1435
+ valueProperty = Object.getOwnPropertyDescriptor(el, "value");
1436
+ if (valueProperty && valueProperty.get) {
1437
+ if (el._valueGet) {
1438
+ Object.defineProperty(el, "value", {
1439
+ get: el._valueGet,
1440
+ set: el._valueSet
1441
+ });
1442
+ }
1443
+ } else if (document.__lookupGetter__ && el.__lookupGetter__("value")) {
1444
+ if (el._valueGet) {
1445
+ el.__defineGetter__("value", el._valueGet);
1446
+ el.__defineSetter__("value", el._valueSet);
1447
+ }
1448
+ }
1449
+ try { //try catch needed for IE7 as it does not supports deleting fns
1450
+ delete el._valueGet;
1451
+ delete el._valueSet;
1452
+ } catch (e) {
1453
+ el._valueGet = undefined;
1454
+ el._valueSet = undefined;
1455
+
1456
+ }
1457
+ break;
1458
+ }
1459
+ }
1460
+ };
1461
+
1462
+ $.inputmask = {
1463
+ //options default
1464
+ defaults: {
1465
+ placeholder: "_",
1466
+ optionalmarker: { start: "[", end: "]" },
1467
+ quantifiermarker: { start: "{", end: "}" },
1468
+ groupmarker: { start: "(", end: ")" },
1469
+ alternatormarker: "|",
1470
+ escapeChar: "\\",
1471
+ mask: null,
1472
+ oncomplete: $.noop, //executes when the mask is complete
1473
+ onincomplete: $.noop, //executes when the mask is incomplete and focus is lost
1474
+ oncleared: $.noop, //executes when the mask is cleared
1475
+ repeat: 0, //repetitions of the mask: * ~ forever, otherwise specify an integer
1476
+ greedy: true, //true: allocated buffer for the mask and repetitions - false: allocate only if needed
1477
+ autoUnmask: false, //automatically unmask when retrieving the value with $.fn.val or value if the browser supports __lookupGetter__ or getOwnPropertyDescriptor
1478
+ clearMaskOnLostFocus: true,
1479
+ insertMode: true, //insert the input or overwrite the input
1480
+ clearIncomplete: false, //clear the incomplete input on blur
1481
+ aliases: {}, //aliases definitions => see jquery.inputmask.extensions.js
1482
+ alias: null,
1483
+ onKeyUp: $.noop, //override to implement autocomplete on certain keys for example
1484
+ onKeyDown: $.noop, //override to implement autocomplete on certain keys for example
1485
+ onBeforeMask: undefined, //executes before masking the initial value to allow preprocessing of the initial value. args => initialValue, opts => return processedValue
1486
+ onBeforePaste: undefined, //executes before masking the pasted value to allow preprocessing of the pasted value. args => pastedValue, opts => return processedValue
1487
+ onUnMask: undefined, //executes after unmasking to allow postprocessing of the unmaskedvalue. args => maskedValue, unmaskedValue, opts
1488
+ showMaskOnFocus: true, //show the mask-placeholder when the input has focus
1489
+ showMaskOnHover: true, //show the mask-placeholder when hovering the empty input
1490
+ onKeyValidation: $.noop, //executes on every key-press with the result of isValid. Params: result, opts
1491
+ skipOptionalPartCharacter: " ", //a character which can be used to skip an optional part of a mask
1492
+ showTooltip: false, //show the activemask as tooltip
1493
+ numericInput: false, //numericInput input direction style (input shifts to the left while holding the caret position)
1494
+ getLastValidPosition: undefined, //override getLastValidPosition - args => maskset, closestTo, opts - return position (int)
1495
+ rightAlign: false, //align to the right
1496
+ //numeric basic properties
1497
+ radixPoint: "", //".", // | ","
1498
+ //numeric basic properties
1499
+ definitions: {
1500
+ '9': {
1501
+ validator: "[0-9]",
1502
+ cardinality: 1,
1503
+ definitionSymbol: "*"
1504
+ },
1505
+ 'a': {
1506
+ validator: "[A-Za-z\u0410-\u044F\u0401\u0451]",
1507
+ cardinality: 1,
1508
+ definitionSymbol: "*"
1509
+ },
1510
+ '*': {
1511
+ validator: "[A-Za-z\u0410-\u044F\u0401\u04510-9]",
1512
+ cardinality: 1
1513
+ }
1514
+ },
1515
+ keyCode: {
1516
+ ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, COMMAND: 91, COMMAND_LEFT: 91, COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, MENU: 93, NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108,
1517
+ NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
1518
+ },
1519
+ //specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
1520
+ ignorables: [8, 9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123],
1521
+ isComplete: undefined //override for isComplete - args => buffer, opts - return true || false
1522
+ },
1523
+ masksCache: {},
1524
+ escapeRegex: function (str) {
1525
+ var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
1526
+ return str.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'gim'), '\\$1');
1527
+ },
1528
+ format: function (value, options) {
1529
+ var opts = $.extend(true, {}, $.inputmask.defaults, options);
1530
+ resolveAlias(opts.alias, options, opts);
1531
+ return maskScope({ "action": "format", "value": value }, generateMaskSet(opts), opts);
1532
+ },
1533
+ isValid: function (value, options) {
1534
+ var opts = $.extend(true, {}, $.inputmask.defaults, options);
1535
+ resolveAlias(opts.alias, options, opts);
1536
+ return maskScope({ "action": "isValid", "value": value }, generateMaskSet(opts), opts);
1537
+ }
1538
+ };
1539
+
1540
+ $.fn.inputmask = function (fn, options, targetScope, targetData, msk) {
1541
+ targetScope = targetScope || maskScope;
1542
+ targetData = targetData || "_inputmask";
1543
+ function importAttributeOptions(npt, opts) {
1544
+ var $npt = $(npt);
1545
+ for (var option in opts) {
1546
+ var optionData = $npt.data("inputmask-" + option.toLowerCase());
1547
+ if (optionData != undefined)
1548
+ opts[option] = optionData;
1549
+ }
1550
+ return opts;
1551
+ }
1552
+ var opts = $.extend(true, {}, $.inputmask.defaults, options),
1553
+ maskset;
1554
+
1555
+ if (typeof fn === "string") {
1556
+ switch (fn) {
1557
+ case "mask":
1558
+ //resolve possible aliases given by options
1559
+ resolveAlias(opts.alias, options, opts);
1560
+ maskset = generateMaskSet(opts);
1561
+ if (maskset.length == 0) { return this; }
1562
+
1563
+ return this.each(function () {
1564
+ targetScope({ "action": "mask", "el": this }, $.extend(true, {}, $.isArray(maskset) && targetScope === maskScope ? maskset[0] : maskset), importAttributeOptions(this, opts));
1565
+ });
1566
+ case "unmaskedvalue":
1567
+ var $input = $(this);
1568
+ if ($input.data(targetData)) {
1569
+ return targetScope({ "action": "unmaskedvalue", "$input": $input });
1570
+ } else return $input.val();
1571
+ case "remove":
1572
+ return this.each(function () {
1573
+ var $input = $(this);
1574
+ if ($input.data(targetData)) {
1575
+ targetScope({ "action": "remove", "el": this });
1576
+ }
1577
+ });
1578
+ case "getemptymask": //return the default (empty) mask value, usefull for setting the default value in validation
1579
+ if (this.data(targetData)) {
1580
+ return targetScope({ "action": "getemptymask", "el": this });
1581
+ }
1582
+ else return "";
1583
+ case "hasMaskedValue": //check wheter the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value
1584
+ return this.data(targetData) ? !this.data(targetData)['opts'].autoUnmask : false;
1585
+ case "isComplete":
1586
+ if (this.data(targetData)) {
1587
+ return targetScope({ "action": "isComplete", "buffer": this[0]._valueGet().split(''), "el": this });
1588
+ } else return true;
1589
+ case "getmetadata": //return mask metadata if exists
1590
+ if (this.data(targetData)) {
1591
+ maskset = this.data(targetData)['maskset'];
1592
+ return maskset['metadata'];
1593
+ }
1594
+ else return undefined;
1595
+ case "_detectScope":
1596
+ resolveAlias(opts.alias, options, opts);
1597
+ if (msk != undefined && !resolveAlias(msk, options, opts) && $.inArray(msk, ["mask", "unmaskedvalue", "remove", "getemptymask", "hasMaskedValue", "isComplete", "getmetadata", "_detectScope"]) == -1) {
1598
+ opts.mask = msk;
1599
+ }
1600
+ if ($.isFunction(opts.mask)) {
1601
+ opts.mask = opts.mask.call(this, opts);
1602
+ }
1603
+ return $.isArray(opts.mask);
1604
+ default:
1605
+ //check if the fn is an alias
1606
+ if (!resolveAlias(fn, options, opts)) {
1607
+ //maybe fn is a mask so we try
1608
+ //set mask
1609
+ opts.mask = fn;
1610
+ }
1611
+ maskset = generateMaskSet(opts);
1612
+ if (maskset == undefined) { return this; }
1613
+ return this.each(function () {
1614
+ targetScope({ "action": "mask", "el": this }, $.extend(true, {}, $.isArray(maskset) && targetScope === maskScope ? maskset[0] : maskset), importAttributeOptions(this, opts));
1615
+ });
1616
+ }
1617
+ } else if (typeof fn == "object") {
1618
+ opts = $.extend(true, {}, $.inputmask.defaults, fn);
1619
+
1620
+ resolveAlias(opts.alias, fn, opts); //resolve aliases
1621
+ maskset = generateMaskSet(opts);
1622
+ if (maskset == undefined) { return this; }
1623
+ return this.each(function () {
1624
+ targetScope({ "action": "mask", "el": this }, $.extend(true, {}, $.isArray(maskset) && targetScope === maskScope ? maskset[0] : maskset), importAttributeOptions(this, opts));
1625
+ });
1626
+ } else if (fn == undefined) {
1627
+ //look for data-inputmask atribute - the attribute should only contain optipns
1628
+ return this.each(function () {
1629
+ var attrOptions = $(this).attr("data-inputmask");
1630
+ if (attrOptions && attrOptions != "") {
1631
+ try {
1632
+ attrOptions = attrOptions.replace(new RegExp("'", "g"), '"');
1633
+ var dataoptions = $.parseJSON("{" + attrOptions + "}");
1634
+ $.extend(true, dataoptions, options);
1635
+ opts = $.extend(true, {}, $.inputmask.defaults, dataoptions);
1636
+ resolveAlias(opts.alias, dataoptions, opts);
1637
+ opts.alias = undefined;
1638
+ $(this).inputmask("mask", opts, targetScope);
1639
+ } catch (ex) { } //need a more relax parseJSON
1640
+ }
1641
+ });
1642
+ }
1643
+ };
1644
+ }
1645
+ })(jQuery);
1646
+
1647
+ jQuery(document).ready(function($){
1648
+ $("[data-inputmask]").inputmask();
1649
+ });
1650
+
1651
+
1652
+
fields/phone/preview.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <div class="preview-caldera-config-group">
2
+ {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
+ <div class="preview-caldera-config-field">
4
+ <input {{#if hide_label}}placeholder="{{label}}"{{else}}placeholder="{{config/placeholder}}"{{/if}} type="text" class="preview-field-config" value="{{config/default}}">
5
+ <span class="help-block">{{caption}}</span>
6
+ </div>
7
+ </div>
fields/radio/field.php CHANGED
@@ -8,11 +8,15 @@
8
 
9
  <?php }else{
10
  foreach($field['config']['option'] as $option_key=>$option){
 
 
 
 
11
  ?>
12
  <?php if(empty($field['config']['inline'])){ ?>
13
  <div class="radio">
14
  <?php } ?>
15
- <label<?php if(!empty($field['config']['inline'])){ ?> class="radio-inline"<?php } ?>><input type="radio" id="<?php echo $field_id . '_' . $option_key; ?>" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo $option['value']; ?>" <?php if( $field_value == $option['value'] ){ ?>checked="true"<?php } ?> <?php echo $field_required; ?>> <?php echo $option['label']; ?></label>&nbsp;
16
  <?php if(empty($field['config']['inline'])){ ?>
17
  </div>
18
  <?php } ?>
8
 
9
  <?php }else{
10
  foreach($field['config']['option'] as $option_key=>$option){
11
+ if(!isset($option['value'])){
12
+ $option['value'] = htmlspecialchars( $option['label'] );
13
+ }
14
+
15
  ?>
16
  <?php if(empty($field['config']['inline'])){ ?>
17
  <div class="radio">
18
  <?php } ?>
19
+ <label<?php if(!empty($field['config']['inline'])){ ?> class="radio-inline"<?php } ?>><input type="radio" id="<?php echo $field_id . '_' . $option_key; ?>" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo $option['value']; ?>" <?php if( $field_value == $option['value'] || $field_value == $option_key ){ ?>checked="true"<?php } ?> <?php echo $field_required; ?>> <?php echo $option['label']; ?></label>&nbsp;
20
  <?php if(empty($field['config']['inline'])){ ?>
21
  </div>
22
  <?php } ?>
fields/radio/preview.php CHANGED
@@ -6,7 +6,7 @@
6
  {{#unless ../config/inline}}
7
  <div>
8
  {{/unless}}
9
- <label style="margin: 0px 10px 0px 0px;"><input type="radio" class="preview-field-config" {{#is default value=true}}checked="checked"{{/is}}> {{label}}</label>
10
  {{#unless ../config/inline}}
11
  </div>
12
  {{/unless}}
6
  {{#unless ../config/inline}}
7
  <div>
8
  {{/unless}}
9
+ <label style="margin: 0px 10px 0px 0px;"><input type="radio" class="preview-field-config" {{#is ../config/default value="@key"}}checked="checked"{{/is}}> {{label}}</label>
10
  {{#unless ../config/inline}}
11
  </div>
12
  {{/unless}}
fields/range_slider/config.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*<div class="caldera-config-group">
3
+ <label for="{{_id}}_pollyfill"><?php echo __('Polyfill', 'caldera-forms'); ?></label>
4
+ <div class="caldera-config-field">
5
+ <label><input id="{{_id}}_pollyfill_check" type="checkbox" class="field-config" name="{{_name}}[pollyfill]" value="1" {{#if pollyfill}}checked="checked"{{/if}}> <?php echo __('Use only on old browsers.','caldera-forms'); ?></label>
6
+ </div>
7
+ </div>*/
8
+ ?>
9
+ <div class="caldera-config-group">
10
+ <label for="{{_id}}_default"><?php echo __('Default', 'caldera-forms'); ?></label>
11
+ <div class="caldera-config-field">
12
+ <input id="{{_id}}_default" type="text" class="block-input field-config" name="{{_name}}[default]" value="{{default}}" style="width:70px;">
13
+ </div>
14
+ </div>
15
+ <div id="{{_id}}_style">
16
+ <div class="caldera-config-group">
17
+ <label for="{{_id}}_trackcolor"><?php echo __('Track', 'caldera-forms'); ?></label>
18
+ <div class="caldera-config-field">
19
+ <input id="{{_id}}_trackcolor" type="text" class="minicolor-picker field-config" name="{{_name}}[trackcolor]" value="{{trackcolor}}">
20
+ </div>
21
+ </div>
22
+ <div class="caldera-config-group">
23
+ <label for="{{_id}}_color"><?php echo __('Highlight', 'caldera-forms'); ?></label>
24
+ <div class="caldera-config-field">
25
+ <input id="{{_id}}_color" type="text" class="minicolor-picker field-config" name="{{_name}}[color]" value="{{color}}">
26
+ </div>
27
+ </div>
28
+ <div class="caldera-config-group">
29
+ <label for="{{_id}}_handle"><?php echo __('Handle', 'caldera-forms'); ?></label>
30
+ <div class="caldera-config-field">
31
+ <input id="{{_id}}_handle" type="text" class="minicolor-picker field-config" name="{{_name}}[handle]" value="{{handle}}">
32
+ </div>
33
+ </div>
34
+ <div class="caldera-config-group">
35
+ <label for="{{_id}}_handleborder"><?php echo __('Border', 'caldera-forms'); ?></label>
36
+ <div class="caldera-config-field">
37
+ <input id="{{_id}}_handleborder" type="text" class="minicolor-picker field-config" name="{{_name}}[handleborder]" value="{{handleborder}}">
38
+ </div>
39
+ </div>
40
+ </div>
41
+ <div class="caldera-config-group">
42
+ <label for="{{_id}}_step"><?php echo __('Steps', 'caldera-forms'); ?></label>
43
+ <div class="caldera-config-field">
44
+ <input id="{{_id}}_step" type="text" class="block-input field-config" name="{{_name}}[step]" value="{{step}}" style="width:70px;">
45
+ </div>
46
+ </div>
47
+ <div class="caldera-config-group">
48
+ <label for="{{_id}}_min"><?php echo __('Minimum', 'caldera-forms'); ?></label>
49
+ <div class="caldera-config-field">
50
+ <input id="{{_id}}_min" type="text" class="block-input field-config" name="{{_name}}[min]" value="{{min}}" style="width:70px;">
51
+ </div>
52
+ </div>
53
+ <div class="caldera-config-group">
54
+ <label for="{{_id}}_max"><?php echo __('Maximum', 'caldera-forms'); ?></label>
55
+ <div class="caldera-config-field">
56
+ <input id="{{_id}}_max" type="text" class="block-input field-config" name="{{_name}}[max]" value="{{max}}" style="width:70px;">
57
+ </div>
58
+ </div>
59
+ <div class="caldera-config-group">
60
+ <label for="{{_id}}_showval"><?php echo __('Show Value', 'caldera-forms'); ?></label>
61
+ <div class="caldera-config-field">
62
+ <input id="{{_id}}_showval" type="checkbox" class="field-config" name="{{_name}}[showval]" value="1" {{#if showval}}checked="checked"{{/if}}>
63
+ </div>
64
+ </div>
65
+ <div class="caldera-config-group">
66
+ <label for="{{_id}}_prefix"><?php echo __('Prefix', 'caldera-forms'); ?></label>
67
+ <div class="caldera-config-field">
68
+ <input id="{{_id}}_prefix" type="text" class="block-input field-config" name="{{_name}}[prefix]" value="{{prefix}}" style="width:70px;">
69
+ </div>
70
+ </div>
71
+ <div class="caldera-config-group">
72
+ <label for="{{_id}}_suffix"><?php echo __('Suffix', 'caldera-forms'); ?></label>
73
+ <div class="caldera-config-field">
74
+ <input id="{{_id}}_suffix" type="text" class="block-input field-config" name="{{_name}}[suffix]" value="{{suffix}}" style="width:70px;">
75
+ </div>
76
+ </div>
77
+ {{#script}}
78
+ jQuery(function($){
79
+ jQuery('#{{_id}}_trackcolor').miniColors();
80
+ jQuery('#{{_id}}_color').miniColors();
81
+ jQuery('#{{_id}}_handle').miniColors();
82
+ jQuery('#{{_id}}_handleborder').miniColors();
83
+
84
+ /*jQuery('#{{_id}}_pollyfill_check').on('change', function(){
85
+
86
+ var clicked = jQuery(this);
87
+ if(clicked.prop('checked')){
88
+ jQuery('#{{_id}}_style').hide();
89
+ }else{
90
+ jQuery('#{{_id}}_style').show();
91
+ }
92
+ });
93
+ jQuery('#{{_id}}_pollyfill_check').trigger('change');*/
94
+ });
95
+ {{/script}}
96
+
97
+
98
+
99
+
fields/range_slider/field.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $polyfill = 'false';
3
+ if(!empty($field['config']['pollyfill'])){
4
+ $polyfill = 'true';
5
+ }
6
+ if(!empty($field['config']['suffix'])){
7
+ $field['config']['suffix'] = self::do_magic_tags($field['config']['suffix']);
8
+ }
9
+ if(!empty($field['config']['prefix'])){
10
+ $field['config']['prefix'] = self::do_magic_tags($field['config']['prefix']);
11
+ }
12
+
13
+ ?><div class="<?php echo $field_wrapper_class; ?>">
14
+ <?php echo $field_label; ?>
15
+ <div class="<?php echo $field_input_class; ?>">
16
+ <div style="position: relative;" <?php if(!empty($field['config']['showval'])){ ?>class="row"<?php } ?>>
17
+ <?php if(!empty($field['config']['showval'])){ ?><div class="col-xs-9" style="margin: <?php if(!empty($field['config']['pollyfill'])){ echo '2px'; }else{ echo '8px'; } ?> 0px;"><?php }else{ ?><div style="margin: <?php if(!empty($field['config']['pollyfill'])){ echo '6px'; }else{ echo '12px'; } ?> 0px;"><?php } ?>
18
+ <input id="<?php echo $field_id; ?>" type="range" data-handle="<?php echo $field['config']['handle']; ?>" data-trackcolor="<?php echo $field['config']['trackcolor']; ?>" data-handleborder="<?php echo $field['config']['handleborder']; ?>" data-color="<?php echo $field['config']['color']; ?>" data-field="<?php echo $field_base_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo $field_value; ?>" min="<?php echo $field['config']['min']; ?>" max="<?php echo $field['config']['max']; ?>" step="<?php echo $field['config']['step']; ?>" <?php echo $field_required; ?>>
19
+ </div>
20
+ <?php if(!empty($field['config']['showval'])){ ?><div class="col-xs-3"><?php if(!empty($field['config']['prefix'])){echo $field['config']['prefix']; } ?><span id="<?php echo $field_id; ?>_value"><?php echo $field_value; ?></span><?php if(!empty($field['config']['suffix'])){echo $field['config']['suffix']; } ?></div><?php } ?>
21
+ </div>
22
+ <?php echo $field_caption; ?>
23
+ </div>
24
+ </div>
25
+ <script type="text/javascript">
26
+ jQuery(function($){
27
+
28
+ function init_rangeslider(){
29
+ var el = $('#<?php echo $field_id; ?>'),
30
+ rangeslider;
31
+ <?php if(empty($field['config']['pollyfill'])){ ?>
32
+ if (el.is(':visible')) {
33
+ rangeslider = el.rangeslider({
34
+ onSlide: function(position, value) {
35
+ $('#<?php echo $field_id; ?>_value').html(value);
36
+ },
37
+ polyfill: <?php echo $polyfill; ?>
38
+ });
39
+ rangeslider.parent().find('.rangeslider').css('backgroundColor', rangeslider.data('trackcolor'));
40
+ rangeslider.parent().find('.rangeslider__fill').css('backgroundColor', rangeslider.data('color'));
41
+ rangeslider.parent().find('.rangeslider__handle').css('backgroundColor', rangeslider.data('handle')).css('borderColor', rangeslider.data('handleborder'));
42
+ }else{
43
+ el.rangeslider('destroy');
44
+ }
45
+ <?php }else{ ?>
46
+ // pollyfill support
47
+ el.on('change', function(){
48
+ $('#<?php echo $field_id; ?>_value').html(this.value);
49
+ }).css("width", "100%");
50
+ <?php } ?>
51
+ }
52
+ <?php if(empty($field['config']['pollyfill'])){ ?>
53
+ // setup tabs
54
+ $(document).on('cf.pagenav', function(){
55
+ init_rangeslider();
56
+ });
57
+ <?php } ?>
58
+ // init slider
59
+ init_rangeslider();
60
+
61
+ });
62
+ </script>
fields/range_slider/preview.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="preview-caldera-config-group">
2
+ {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
+ <div class="preview-caldera-config-field">
4
+ {{#if config/showval}}<div class="col-xs-9" style="margin: {{#if config/pollyfill}}2px{{else}}6px{{/if}} 0px;">{{else}}<div style="margin: {{#if config/pollyfill}}2px{{else}}6px{{/if}} 0px;">{{/if}}
5
+ <input id="{{id}}_rangeslider" type="range" data-trackcolor="{{config/trackcolor}}" data-color="{{config/color}}" data-handle="{{config/handle}}" data-handleborder="{{config/handleborder}}" min="{{config/min}}" max="{{config/max}}" step="{{config/step}}" value="{{config/default}}" style="width:100%">
6
+ </div>{{#if config/showval}}
7
+ <div class="col-xs-3">
8
+ {{config/prefix}}<span id="{{id}}_value">{{config/default}}</span>{{config/suffix}}
9
+ </div>{{/if}}
10
+ <span class="help-block">{{caption}}</span>
11
+ </div><div class="clearfix"></div>
12
+ </div>
13
+ {{#script}}
14
+ var rangeslide{{id}} = jQuery('#{{id}}_rangeslider').rangeslider({
15
+ onSlide: function(position, value) {
16
+ jQuery('#{{id}}_value').html(value);
17
+ },
18
+ polyfill: {{#if config/pollyfill}}true{{else}}false{{/if}}
19
+ });
20
+ rangeslide{{id}}.parent().find('.rangeslider').css('backgroundColor', rangeslide{{id}}.data('trackcolor'));
21
+ rangeslide{{id}}.parent().find('.rangeslider__fill').css('backgroundColor', rangeslide{{id}}.data('color'));
22
+ rangeslide{{id}}.parent().find('.rangeslider__handle').css('backgroundColor', rangeslide{{id}}.data('handle'));
23
+ rangeslide{{id}}.parent().find('.rangeslider__handle').css('borderColor', rangeslide{{id}}.data('handleborder'));
24
+ {{/script}}
fields/range_slider/rangeslider.css ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .rangeslider,
2
+ .rangeslider__fill {
3
+ background: #e6e6e6;
4
+ display: block;
5
+ height: 8px;
6
+ width: 100%;
7
+ -webkit-border-radius: 10px;
8
+ -moz-border-radius: 10px;
9
+ -ms-border-radius: 10px;
10
+ -o-border-radius: 10px;
11
+ border-radius: 10px;
12
+ }
13
+
14
+ .rangeslider {
15
+ position: relative;
16
+ }
17
+
18
+ .rangeslider--disabled {
19
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
20
+ opacity: 0.4;
21
+ }
22
+
23
+ .rangeslider__fill {
24
+ background: #00ff00;
25
+ position: absolute;
26
+ top: 0;
27
+ }
28
+
29
+ .rangeslider__handle {
30
+ background: white;
31
+ border: 1px solid #ccc;
32
+ cursor: pointer;
33
+ display: inline-block;
34
+ width: 25px;
35
+ height: 25px;
36
+ position: absolute;
37
+ top: -9px;
38
+ -webkit-border-radius: 50%;
39
+ -moz-border-radius: 50%;
40
+ -ms-border-radius: 50%;
41
+ -o-border-radius: 50%;
42
+ border-radius: 50%;
43
+ }
44
+
45
+
46
+ input[type="range"]:focus + .rangeslider .rangeslider__handle {
47
+ -webkit-box-shadow: 0 0 3px rgba(100,100,100, 0.9);
48
+ -moz-box-shadow: 0 0 3px rgba(100,100,100, 0.9);
49
+ box-shadow: 0 0 3px rgba(100,100,100, 0.9);
50
+ }
fields/range_slider/rangeslider.js ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! rangeslider.js - v0.3.1 | (c) 2014 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */
2
+ 'use strict';
3
+
4
+ (function(factory) {
5
+ if (typeof define === 'function' && define.amd) {
6
+ // AMD. Register as an anonymous module.
7
+ define(['jquery'], factory);
8
+ }
9
+ else if (typeof exports === 'object') {
10
+ // CommonJS
11
+ factory(require('jquery'));
12
+ } else {
13
+ // Browser globals
14
+ factory(jQuery);
15
+ }
16
+ }(function($) {
17
+
18
+ /**
19
+ * Range feature detection
20
+ * @return {Boolean}
21
+ */
22
+ function supportsRange() {
23
+ var input = document.createElement('input');
24
+ input.setAttribute('type', 'range');
25
+ return input.type !== 'text';
26
+ }
27
+
28
+ var pluginName = 'rangeslider',
29
+ pluginInstances = [],
30
+ inputrange = supportsRange(),
31
+ defaults = {
32
+ polyfill: true,
33
+ rangeClass: 'rangeslider',
34
+ disabledClass: 'rangeslider--disabled',
35
+ fillClass: 'rangeslider__fill',
36
+ handleClass: 'rangeslider__handle',
37
+ startEvent: ['mousedown', 'touchstart', 'pointerdown'],
38
+ moveEvent: ['mousemove', 'touchmove', 'pointermove'],
39
+ endEvent: ['mouseup', 'touchend', 'pointerup']
40
+ };
41
+
42
+ /**
43
+ * Delays a function for the given number of milliseconds, and then calls
44
+ * it with the arguments supplied.
45
+ *
46
+ * @param {Function} fn [description]
47
+ * @param {Number} wait [description]
48
+ * @return {Function}
49
+ */
50
+ function delay(fn, wait) {
51
+ var args = Array.prototype.slice.call(arguments, 2);
52
+ return setTimeout(function(){ return fn.apply(null, args); }, wait);
53
+ }
54
+
55
+ /**
56
+ * Returns a debounced function that will make sure the given
57
+ * function is not triggered too much.
58
+ *
59
+ * @param {Function} fn Function to debounce.
60
+ * @param {Number} debounceDuration OPTIONAL. The amount of time in milliseconds for which we will debounce the function. (defaults to 100ms)
61
+ * @return {Function}
62
+ */
63
+ function debounce(fn, debounceDuration) {
64
+ debounceDuration = debounceDuration || 100;
65
+ return function() {
66
+ if (!fn.debouncing) {
67
+ var args = Array.prototype.slice.apply(arguments);
68
+ fn.lastReturnVal = fn.apply(window, args);
69
+ fn.debouncing = true;
70
+ }
71
+ clearTimeout(fn.debounceTimeout);
72
+ fn.debounceTimeout = setTimeout(function(){
73
+ fn.debouncing = false;
74
+ }, debounceDuration);
75
+ return fn.lastReturnVal;
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Plugin
81
+ * @param {String} element
82
+ * @param {Object} options
83
+ */
84
+ function Plugin(element, options) {
85
+ this.$window = $(window);
86
+ this.$document = $(document);
87
+ this.$element = $(element);
88
+ this.options = $.extend( {}, defaults, options );
89
+ this._defaults = defaults;
90
+ this._name = pluginName;
91
+ this.startEvent = this.options.startEvent.join('.' + pluginName + ' ') + '.' + pluginName;
92
+ this.moveEvent = this.options.moveEvent.join('.' + pluginName + ' ') + '.' + pluginName;
93
+ this.endEvent = this.options.endEvent.join('.' + pluginName + ' ') + '.' + pluginName;
94
+ this.polyfill = this.options.polyfill;
95
+ this.onInit = this.options.onInit;
96
+ this.onSlide = this.options.onSlide;
97
+ this.onSlideEnd = this.options.onSlideEnd;
98
+
99
+ // Plugin should only be used as a polyfill
100
+ if (this.polyfill) {
101
+ // Input range support?
102
+ if (inputrange) { return false; }
103
+ }
104
+
105
+ this.identifier = 'js-' + pluginName + '-' +(+new Date());
106
+ this.min = parseFloat(this.$element[0].getAttribute('min') || 0);
107
+ this.max = parseFloat(this.$element[0].getAttribute('max') || 100);
108
+ this.value = parseFloat(this.$element[0].value || this.min + (this.max-this.min)/2);
109
+ this.step = parseFloat(this.$element[0].getAttribute('step') || 1);
110
+ this.$fill = $('<div class="' + this.options.fillClass + '" />');
111
+ this.$handle = $('<div class="' + this.options.handleClass + '" />');
112
+ this.$range = $('<div class="' + this.options.rangeClass + '" id="' + this.identifier + '" />').insertAfter(this.$element).prepend(this.$fill, this.$handle);
113
+
114
+ // visually hide the input
115
+ this.$element.css({
116
+ 'position': 'absolute',
117
+ 'width': '1px',
118
+ 'height': '1px',
119
+ 'overflow': 'hidden',
120
+ 'opacity': '0'
121
+ });
122
+
123
+ // Store context
124
+ this.handleDown = $.proxy(this.handleDown, this);
125
+ this.handleMove = $.proxy(this.handleMove, this);
126
+ this.handleEnd = $.proxy(this.handleEnd, this);
127
+
128
+ this.init();
129
+
130
+ // Attach Events
131
+ var _this = this;
132
+ this.$window.on('resize' + '.' + pluginName, debounce(function() {
133
+ // Simulate resizeEnd event.
134
+ delay(function() { _this.update(); }, 300);
135
+ }, 20));
136
+
137
+ this.$document.on(this.startEvent, '#' + this.identifier + ':not(.' + this.options.disabledClass + ')', this.handleDown);
138
+
139
+ // Listen to programmatic value changes
140
+ this.$element.on('change' + '.' + pluginName, function(e, data) {
141
+ if (data && data.origin === pluginName) {
142
+ return;
143
+ }
144
+
145
+ var value = e.target.value,
146
+ pos = _this.getPositionFromValue(value);
147
+ _this.setPosition(pos);
148
+ });
149
+ }
150
+
151
+ Plugin.prototype.init = function() {
152
+ if (this.onInit && typeof this.onInit === 'function') {
153
+ this.onInit();
154
+ }
155
+ this.update();
156
+ };
157
+
158
+ Plugin.prototype.update = function() {
159
+ this.handleWidth = this.$handle[0].offsetWidth;
160
+ this.rangeWidth = this.$range[0].offsetWidth;
161
+ this.maxHandleX = this.rangeWidth - this.handleWidth;
162
+ this.grabX = this.handleWidth / 2;
163
+ this.position = this.getPositionFromValue(this.value);
164
+
165
+ // Consider disabled state
166
+ if (this.$element[0].disabled) {
167
+ this.$range.addClass(this.options.disabledClass);
168
+ } else {
169
+ this.$range.removeClass(this.options.disabledClass);
170
+ }
171
+
172
+ this.setPosition(this.position);
173
+ };
174
+
175
+ Plugin.prototype.handleDown = function(e) {
176
+ e.preventDefault();
177
+ this.$document.on(this.moveEvent, this.handleMove);
178
+ this.$document.on(this.endEvent, this.handleEnd);
179
+
180
+ // If we click on the handle don't set the new position
181
+ if ((' ' + e.target.className + ' ').replace(/[\n\t]/g, ' ').indexOf(this.options.handleClass) > -1) {
182
+ return;
183
+ }
184
+
185
+ var posX = this.getRelativePosition(this.$range[0], e),
186
+ handleX = this.getPositionFromNode(this.$handle[0]) - this.getPositionFromNode(this.$range[0]);
187
+
188
+ this.setPosition(posX - this.grabX);
189
+
190
+ if (posX >= handleX && posX < handleX + this.handleWidth) {
191
+ this.grabX = posX - handleX;
192
+ }
193
+ };
194
+
195
+ Plugin.prototype.handleMove = function(e) {
196
+ e.preventDefault();
197
+ var posX = this.getRelativePosition(this.$range[0], e);
198
+ this.setPosition(posX - this.grabX);
199
+ };
200
+
201
+ Plugin.prototype.handleEnd = function(e) {
202
+ e.preventDefault();
203
+ this.$document.off(this.moveEvent, this.handleMove);
204
+ this.$document.off(this.endEvent, this.handleEnd);
205
+
206
+ var posX = this.getRelativePosition(this.$range[0], e);
207
+ if (this.onSlideEnd && typeof this.onSlideEnd === 'function') {
208
+ this.onSlideEnd(posX - this.grabX, this.value);
209
+ }
210
+ };
211
+
212
+ Plugin.prototype.cap = function(pos, min, max) {
213
+ if (pos < min) { return min; }
214
+ if (pos > max) { return max; }
215
+ return pos;
216
+ };
217
+
218
+ Plugin.prototype.setPosition = function(pos) {
219
+ var value, left;
220
+
221
+ // Snapping steps
222
+ value = (this.getValueFromPosition(this.cap(pos, 0, this.maxHandleX)) / this.step) * this.step;
223
+ left = this.getPositionFromValue(value);
224
+
225
+ // Update ui
226
+ this.$fill[0].style.width = (left + this.grabX) + 'px';
227
+ this.$handle[0].style.left = left + 'px';
228
+ this.setValue(value);
229
+
230
+ // Update globals
231
+ this.position = left;
232
+ this.value = value;
233
+
234
+ if (this.onSlide && typeof this.onSlide === 'function') {
235
+ this.onSlide(left, value);
236
+ }
237
+ };
238
+
239
+ Plugin.prototype.getPositionFromNode = function(node) {
240
+ var i = 0;
241
+ while (node !== null) {
242
+ i += node.offsetLeft;
243
+ node = node.offsetParent;
244
+ }
245
+ return i;
246
+ };
247
+
248
+ Plugin.prototype.getRelativePosition = function(node, e) {
249
+ return (e.pageX || e.originalEvent.clientX || e.originalEvent.touches[0].clientX || e.currentPoint.x) - this.getPositionFromNode(node);
250
+ };
251
+
252
+ Plugin.prototype.getPositionFromValue = function(value) {
253
+ var percentage, pos;
254
+ percentage = (value - this.min)/(this.max - this.min);
255
+ pos = percentage * this.maxHandleX;
256
+ return pos;
257
+ };
258
+
259
+ Plugin.prototype.getValueFromPosition = function(pos) {
260
+ var percentage, value;
261
+ percentage = ((pos) / (this.maxHandleX || 1));
262
+ value = this.step * Math.ceil((((percentage) * (this.max - this.min)) + this.min) / this.step);
263
+ return Number((value).toFixed(2));
264
+ };
265
+
266
+ Plugin.prototype.setValue = function(value) {
267
+ if (value !== this.value) {
268
+ this.$element.val(value).trigger('change', {origin: pluginName});
269
+ }
270
+ };
271
+
272
+ Plugin.prototype.destroy = function() {
273
+ this.$document.off(this.startEvent, '#' + this.identifier, this.handleDown);
274
+ this.$element
275
+ .off('.' + pluginName)
276
+ .removeAttr('style')
277
+ .removeData('plugin_' + pluginName);
278
+
279
+ // Remove the generated markup
280
+ if (this.$range && this.$range.length) {
281
+ this.$range[0].parentNode.removeChild(this.$range[0]);
282
+ }
283
+
284
+ // Remove global events if there isn't any instance anymore.
285
+ pluginInstances.splice(pluginInstances.indexOf(this.$element[0]),1);
286
+ if (!pluginInstances.length) {
287
+ this.$window.off('.' + pluginName);
288
+ }
289
+ };
290
+
291
+ // A really lightweight plugin wrapper around the constructor,
292
+ // preventing against multiple instantiations
293
+ $.fn[pluginName] = function(options) {
294
+ return this.each(function() {
295
+ var $this = $(this),
296
+ data = $this.data('plugin_' + pluginName);
297
+
298
+ // Create a new instance.
299
+ if (!data) {
300
+ $this.data('plugin_' + pluginName, (data = new Plugin(this, options)));
301
+ pluginInstances.push(this);
302
+ }
303
+
304
+ // Make it possible to access methods from public.
305
+ // e.g `$element.rangeslider('method');`
306
+ if (typeof options === 'string') {
307
+ data[options]();
308
+ }
309
+ });
310
+ };
311
+
312
+ }));
fields/range_slider/rangeslider.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /*! rangeslider.js - v0.3.1 | (c) 2014 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */
2
+ "use strict";!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(){var a=document.createElement("input");return a.setAttribute("type","range"),"text"!==a.type}function c(a,b){var c=Array.prototype.slice.call(arguments,2);return setTimeout(function(){return a.apply(null,c)},b)}function d(a,b){return b=b||100,function(){if(!a.debouncing){var c=Array.prototype.slice.apply(arguments);a.lastReturnVal=a.apply(window,c),a.debouncing=!0}return clearTimeout(a.debounceTimeout),a.debounceTimeout=setTimeout(function(){a.debouncing=!1},b),a.lastReturnVal}}function e(b,e){if(this.$window=a(window),this.$document=a(document),this.$element=a(b),this.options=a.extend({},i,e),this._defaults=i,this._name=f,this.startEvent=this.options.startEvent.join("."+f+" ")+"."+f,this.moveEvent=this.options.moveEvent.join("."+f+" ")+"."+f,this.endEvent=this.options.endEvent.join("."+f+" ")+"."+f,this.polyfill=this.options.polyfill,this.onInit=this.options.onInit,this.onSlide=this.options.onSlide,this.onSlideEnd=this.options.onSlideEnd,this.polyfill&&h)return!1;this.identifier="js-"+f+"-"+ +new Date,this.min=parseFloat(this.$element[0].getAttribute("min")||0),this.max=parseFloat(this.$element[0].getAttribute("max")||100),this.value=parseFloat(this.$element[0].value||this.min+(this.max-this.min)/2),this.step=parseFloat(this.$element[0].getAttribute("step")||1),this.$fill=a('<div class="'+this.options.fillClass+'" />'),this.$handle=a('<div class="'+this.options.handleClass+'" />'),this.$range=a('<div class="'+this.options.rangeClass+'" id="'+this.identifier+'" />').insertAfter(this.$element).prepend(this.$fill,this.$handle),this.$element.css({position:"absolute",width:"1px",height:"1px",overflow:"hidden",opacity:"0"}),this.handleDown=a.proxy(this.handleDown,this),this.handleMove=a.proxy(this.handleMove,this),this.handleEnd=a.proxy(this.handleEnd,this),this.init();var g=this;this.$window.on("resize."+f,d(function(){c(function(){g.update()},300)},20)),this.$document.on(this.startEvent,"#"+this.identifier+":not(."+this.options.disabledClass+")",this.handleDown),this.$element.on("change."+f,function(a,b){if(!b||b.origin!==f){var c=a.target.value,d=g.getPositionFromValue(c);g.setPosition(d)}})}var f="rangeslider",g=[],h=b(),i={polyfill:!0,rangeClass:"rangeslider",disabledClass:"rangeslider--disabled",fillClass:"rangeslider__fill",handleClass:"rangeslider__handle",startEvent:["mousedown","touchstart","pointerdown"],moveEvent:["mousemove","touchmove","pointermove"],endEvent:["mouseup","touchend","pointerup"]};e.prototype.init=function(){this.onInit&&"function"==typeof this.onInit&&this.onInit(),this.update()},e.prototype.update=function(){this.handleWidth=this.$handle[0].offsetWidth,this.rangeWidth=this.$range[0].offsetWidth,this.maxHandleX=this.rangeWidth-this.handleWidth,this.grabX=this.handleWidth/2,this.position=this.getPositionFromValue(this.value),this.$element[0].disabled?this.$range.addClass(this.options.disabledClass):this.$range.removeClass(this.options.disabledClass),this.setPosition(this.position)},e.prototype.handleDown=function(a){if(a.preventDefault(),this.$document.on(this.moveEvent,this.handleMove),this.$document.on(this.endEvent,this.handleEnd),!((" "+a.target.className+" ").replace(/[\n\t]/g," ").indexOf(this.options.handleClass)>-1)){var b=this.getRelativePosition(this.$range[0],a),c=this.getPositionFromNode(this.$handle[0])-this.getPositionFromNode(this.$range[0]);this.setPosition(b-this.grabX),b>=c&&b<c+this.handleWidth&&(this.grabX=b-c)}},e.prototype.handleMove=function(a){a.preventDefault();var b=this.getRelativePosition(this.$range[0],a);this.setPosition(b-this.grabX)},e.prototype.handleEnd=function(a){a.preventDefault(),this.$document.off(this.moveEvent,this.handleMove),this.$document.off(this.endEvent,this.handleEnd);var b=this.getRelativePosition(this.$range[0],a);this.onSlideEnd&&"function"==typeof this.onSlideEnd&&this.onSlideEnd(b-this.grabX,this.value)},e.prototype.cap=function(a,b,c){return b>a?b:a>c?c:a},e.prototype.setPosition=function(a){var b,c;b=this.getValueFromPosition(this.cap(a,0,this.maxHandleX))/this.step*this.step,c=this.getPositionFromValue(b),this.$fill[0].style.width=c+this.grabX+"px",this.$handle[0].style.left=c+"px",this.setValue(b),this.position=c,this.value=b,this.onSlide&&"function"==typeof this.onSlide&&this.onSlide(c,b)},e.prototype.getPositionFromNode=function(a){for(var b=0;null!==a;)b+=a.offsetLeft,a=a.offsetParent;return b},e.prototype.getRelativePosition=function(a,b){return(b.pageX||b.originalEvent.clientX||b.originalEvent.touches[0].clientX||b.currentPoint.x)-this.getPositionFromNode(a)},e.prototype.getPositionFromValue=function(a){var b,c;return b=(a-this.min)/(this.max-this.min),c=b*this.maxHandleX},e.prototype.getValueFromPosition=function(a){var b,c;return b=a/(this.maxHandleX||1),c=this.step*Math.ceil((b*(this.max-this.min)+this.min)/this.step),Number(c.toFixed(2))},e.prototype.setValue=function(a){a!==this.value&&this.$element.val(a).trigger("change",{origin:f})},e.prototype.destroy=function(){this.$document.off(this.startEvent,"#"+this.identifier,this.handleDown),this.$element.off("."+f).removeAttr("style").removeData("plugin_"+f),this.$range&&this.$range.length&&this.$range[0].parentNode.removeChild(this.$range[0]),g.splice(g.indexOf(this.$element[0]),1),g.length||this.$window.off("."+f)},a.fn[f]=function(b){return this.each(function(){var c=a(this),d=c.data("plugin_"+f);d||(c.data("plugin_"+f,d=new e(this,b)),g.push(this)),"string"==typeof b&&d[b]()})}});
fields/star-rate/cf-raty.css ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @font-face {
2
+ font-family: 'cf-raty';
3
+ src: url('fonts/cf-raty.eot?40481674');
4
+ src: url('fonts/cf-raty.eot?40481674#iefix') format('embedded-opentype'),
5
+ url('fonts/cf-raty.woff?40481674') format('woff'),
6
+ url('fonts/cf-raty.ttf?40481674') format('truetype'),
7
+ url('fonts/cf-raty.svg?40481674#cf-raty') format('svg');
8
+ font-weight: normal;
9
+ font-style: normal;
10
+ }
11
+ /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
12
+ /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
13
+ /*
14
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
15
+ @font-face {
16
+ font-family: 'cf-raty';
17
+ src: url('../font/cf-raty.svg?40481674#cf-raty') format('svg');
18
+ }
19
+ }
20
+ */
21
+
22
+ [class^="raty-"]:before, [class*=" raty-"]:before {
23
+ font-family: "cf-raty";
24
+ font-style: normal;
25
+ font-weight: normal;
26
+ speak: none;
27
+ font-size: 2em;
28
+ display: inline-block;
29
+ text-decoration: inherit;
30
+ width: 1em;
31
+ text-align: center;
32
+ /* opacity: .8; */
33
+
34
+ /* For safety - reset parent styles, that can break glyph codes*/
35
+ font-variant: normal;
36
+ text-transform: none;
37
+
38
+ /* fix buttons height, for twitter bootstrap */
39
+ line-height: 1em;
40
+ }
41
+
42
+ .raty-heart-on:before { content: '\e800'; } /* '' */
43
+ .raty-heart-off:before { content: '\e801'; } /* '' */
44
+ .raty-star-on:before { content: '\e802'; } /* '' */
45
+ .raty-star-off:before { content: '\e803'; } /* '' */
46
+ .raty-circle-on:before { content: '\e804'; } /* '' */
47
+ .raty-circle-off:before { content: '\e805'; } /* '' */
48
+ .raty-dot-off:before { content: '\e806'; } /* '' */
49
+ .raty-dot-on:before { content: '\e807'; } /* '' */
50
+ .raty-face-off:before { content: '\e808'; } /* '' */
51
+ .raty-face-on:before { content: '\e809'; } /* '' */
52
+ .raty-cancel-off:before { content: '\e80a'; } /* '' */
53
+ .raty-cancel-on:before { content: '\e80b'; } /* '' */
fields/star-rate/config.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="caldera-config-group">
2
+ <label for="{{_id}}_number"><?php echo __('Number of Stars', 'caldera-forms-register'); ?></label>
3
+ <div class="caldera-config-field">
4
+ <input id="{{_id}}_number" type="number" class="field-config" name="{{_name}}[number]" value="{{number}}" style="width:70px;">
5
+ </div>
6
+ </div>
7
+ <div class="caldera-config-group">
8
+ <label for="{{_id}}_type"><?php echo __('Star Type', 'caldera-forms-register'); ?></label>
9
+ <div class="caldera-config-field">
10
+ <select id="{{_id}}_type" class="field-config" name="{{_name}}[type]">
11
+ <option value="star"><?php echo __('Star', 'caldera-forms'); ?></option>
12
+ <option value="heart"><?php echo __('Heart', 'caldera-forms'); ?></option>
13
+ <option value="face"><?php echo __('Face', 'caldera-forms'); ?></option>
14
+ <option value="dot"><?php echo __('Dot', 'caldera-forms'); ?></option>
15
+ </select>
16
+ </div>
17
+ </div>
18
+ <div class="caldera-config-group">
19
+ <label for="{{_id}}_size"><?php echo __('Star Size', 'caldera-forms-register'); ?></label>
20
+ <div class="caldera-config-field">
21
+ <input id="{{_id}}_size" type="number" class="field-config" name="{{_name}}[size]" value="{{size}}" style="width:70px;">px
22
+ </div>
23
+ </div>
24
+ <div class="caldera-config-group">
25
+ <label for="{{_id}}_space"><?php echo __('Star Spacing', 'caldera-forms-register'); ?></label>
26
+ <div class="caldera-config-field">
27
+ <input id="{{_id}}_space" type="number" class="field-config" name="{{_name}}[space]" value="{{space}}" style="width:70px;">px
28
+ </div>
29
+ </div>
30
+ <div class="caldera-config-group">
31
+ <label for="{{_id}}_single"><?php echo __('Single Select', 'caldera-forms-register'); ?></label>
32
+ <div class="caldera-config-field">
33
+ <input id="{{_id}}_single" type="checkbox" class="field-config" name="{{_name}}[single]" value="1" {{#if single}}checked="checked"{{/if}}>
34
+ </div>
35
+ </div>
36
+
37
+ <div class="caldera-config-group">
38
+ <label for="{{_id}}_color"><?php echo __('Star Color', 'caldera-forms-register'); ?></label>
39
+ <div class="caldera-config-field">
40
+ <input type="text" class="minicolor-picker field-config" id="{{_id}}_color" name="{{_name}}[color]" value="{{color}}">
41
+ </div>
42
+ </div>
43
+ <div class="caldera-config-group">
44
+ <label for="{{_id}}_track_color"><?php echo __('Track Color', 'caldera-forms-register'); ?></label>
45
+ <div class="caldera-config-field">
46
+ <input type="text" class="minicolor-picker field-config" id="{{_id}}_track_color" name="{{_name}}[track_color]" value="{{track_color}}">
47
+ </div>
48
+ </div>
49
+ <div class="caldera-config-group">
50
+ <label for="{{_id}}_cancel"><?php echo __('Include Cancel', 'caldera-forms-register'); ?></label>
51
+ <div class="caldera-config-field">
52
+ <input id="{{_id}}_cancel" type="checkbox" class="field-config" name="{{_name}}[cancel]" value="1" {{#if cancel}}checked="checked"{{/if}}>
53
+ </div>
54
+ </div>
55
+
56
+ {{#script}}
57
+ jQuery(function($){
58
+ jQuery('#{{_id}}_color').miniColors();
59
+ jQuery('#{{_id}}_track_color').miniColors();
60
+ });
61
+ {{/script}}
fields/star-rate/field.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if(!isset($field['config']['track_color'])){
3
+ $field['config']['track_color'] = '#AFAFAF';
4
+ }
5
+ if(!isset($field['config']['type'])){
6
+ $field['config']['type'] = 'star';
7
+ }
8
+ ?><div class="<?php echo $field_wrapper_class; ?>">
9
+ <?php echo $field_label; ?>
10
+ <div class="<?php echo $field_input_class; ?>">
11
+ <div style="position: relative;">
12
+ <div id="<?php echo $field_id; ?>_stars" style="color:<?php echo $field['config']['track_color']; ?>;font-size:<?php echo floatval( $field['config']['size'] ); ?>px;"></div>
13
+ <input id="<?php echo $field_id; ?>" type="text" data-field="<?php echo $field_base_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo $field_value; ?>" <?php echo $field_required; ?> style="position: absolute; width: 0px; height: 0px; padding: 0px; bottom: 0px; left: 12px; opacity: 0; z-index: -1000;">
14
+ </div>
15
+ <?php echo $field_caption; ?>
16
+ </div>
17
+ </div>
18
+ <script type="text/javascript">
19
+ jQuery(function($){
20
+ $('#<?php echo $field_id; ?>_stars').raty({
21
+ starOff : 'raty-<?php echo $field['config']['type']; ?>-off',
22
+ starOn : 'raty-<?php echo $field['config']['type']; ?>-on',
23
+ target: '#<?php echo $field_id; ?>',
24
+ spaceWidth: <?php echo $field['config']['space']; ?>,
25
+ targetKeep: true, targetType: 'score',
26
+ <?php if(!empty($field_value)){ echo "score: ".$field_value.","; }; ?>
27
+ hints: [1,2,3,4,5],
28
+ number: <?php echo $field['config']['number']; ?>,
29
+ starType: 'f',
30
+ starColor: '<?php echo $field['config']['color']; ?>',
31
+ numberMax: 100,
32
+ click :function(e){
33
+ $('#<?php echo $field_id; ?>').trigger('change');
34
+ }
35
+ <?php if(!empty($field['config']['cancel'])){ echo ",cancel: true"; }; ?>
36
+ <?php if(!empty($field['config']['single'])){ echo ",single: true"; }; ?>
37
+ });
38
+ });
39
+ </script>
fields/star-rate/fonts/cf-raty.eot ADDED
Binary file
fields/star-rate/fonts/cf-raty.svg ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
5
+ <defs>
6
+ <font id="cf-raty" horiz-adv-x="1000" >
7
+ <font-face font-family="cf-raty" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
8
+ <missing-glyph horiz-adv-x="1000" />
9
+ <glyph glyph-name="heart-on" unicode="&#xe800;" d="m0 517q0 123 71 192t196 70q34 0 70-12t67-33 54-38 42-38q20 20 42 38t54 38 67 33 70 12q125 0 196-70t71-192q0-123-128-251l-347-335q-10-10-25-10t-25 10l-348 336q-5 5-15 15t-31 36-38 55-30 67-13 77z" horiz-adv-x="1000" />
10
+ <glyph glyph-name="heart-off" unicode="&#xe801;" d="m0 517q0 123 71 192t196 70q34 0 70-12t67-33 54-38 42-38q20 20 42 38t54 38 67 33 70 12q125 0 196-70t71-192q0-123-128-251l-347-335q-10-10-25-10t-25 10l-348 336q-5 5-15 15t-31 36-38 55-30 67-13 77z m71 0q0-93 105-198l324-312 324 312q105 105 105 198 0 46-12 80t-31 55-46 33-52 18-55 4-62-14-62-36-48-40-34-34q-10-13-27-13t-27 13q-14 15-34 34t-48 40-62 36-62 14-55-4-52-18-46-33-31-55-12-80z" horiz-adv-x="1000" />
11
+ <glyph glyph-name="star-on" unicode="&#xe802;" d="m0 489q0 21 31 26l280 40 126 254q11 23 27 23t28-23l125-254 280-40q32-5 32-26 0-12-15-27l-203-197 48-279q1-4 1-12 0-11-6-19t-17-9q-10 0-22 7l-251 132-250-132q-13-7-23-7-11 0-17 9t-6 19q0 4 1 12l48 279-203 197q-14 15-14 27z" horiz-adv-x="928.6" />
12
+ <glyph glyph-name="star-off" unicode="&#xe803;" d="m0 489q0 21 31 26l280 40 126 254q11 23 27 23t28-23l125-254 280-40q32-5 32-26 0-12-15-27l-203-197 48-279q1-4 1-12 0-28-23-28-10 0-22 7l-251 132-250-132q-13-7-23-7-11 0-17 9t-6 19q0 4 1 12l48 279-203 197q-14 15-14 27z m123-34l171-165-41-235 211 111 211-111-41 235 171 165-235 35-106 213-105-213z" horiz-adv-x="928.6" />
13
+ <glyph glyph-name="circle-on" unicode="&#xe804;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z" horiz-adv-x="857.1" />
14
+ <glyph glyph-name="circle-off" unicode="&#xe805;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m71 0q0-73 29-139t76-113 114-77 139-28 138 28 114 77 76 113 29 139-29 139-76 114-114 76-138 28-139-28-114-76-76-114-29-139z" horiz-adv-x="857.1" />
15
+ <glyph glyph-name="dot-off" unicode="&#xe806;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m125 0q0-83 41-152t110-111 153-41 152 41 110 111 41 152-41 152-110 111-152 41-153-41-110-111-41-152z" horiz-adv-x="857.1" />
16
+ <glyph glyph-name="dot-on" unicode="&#xe807;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m125 0q0-83 41-152t110-111 153-41 152 41 110 111 41 152-41 152-110 111-152 41-153-41-110-111-41-152z m161 0q0 59 42 101t101 42 101-42 41-101-41-101-101-42-101 42-42 101z" horiz-adv-x="857.1" />
17
+ <glyph glyph-name="face-off" unicode="&#xe808;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m71 0q0-73 29-139t76-113 114-77 139-28 138 28 114 77 76 113 29 139-29 139-76 114-114 76-138 28-139-28-114-76-76-114-29-139z m143-107q0 14 11 25t25 11h357q15 0 25-11t11-25-11-25-25-11h-357q-14 0-25 11t-11 25z m0 250q0 29 21 50t51 21 50-21 21-50-21-51-50-21-51 21-21 51z m286 0q0 29 21 50t50 21 51-21 21-50-21-51-51-21-50 21-21 51z" horiz-adv-x="857.1" />
18
+ <glyph glyph-name="face-on" unicode="&#xe809;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m71 0q0-73 29-139t76-113 114-77 139-28 138 28 114 77 76 113 29 139-29 139-76 114-114 76-138 28-139-28-114-76-76-114-29-139z m143 143q0 29 21 50t51 21 50-21 21-50-21-51-50-21-51 21-21 51z m10-243q-4 14 3 27t21 18q14 4 27-2t17-22q14-44 52-72t85-28 84 28 52 72q4 15 18 22t27 2 21-18 2-27q-21-67-77-109t-127-41-128 41-77 109z m276 243q0 29 21 50t50 21 51-21 21-50-21-51-51-21-50 21-21 51z" horiz-adv-x="857.1" />
19
+ <glyph glyph-name="cancel-circled2" unicode="&#xe80a;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m125 0q0-83 41-152t110-111 153-41 152 41 110 111 41 152-41 152-110 111-152 41-153-41-110-111-41-152z m114-89q0 7 6 13l76 76-76 76q-6 6-6 13t6 13l81 82q6 5 13 5t13-5l77-77 76 77q6 5 13 5t13-5l81-82q6-5 6-13t-6-13l-76-76 76-76q6-6 6-13t-6-13l-81-82q-6-5-13-5t-13 5l-76 77-77-77q-5-5-13-5t-13 5l-81 82q-6 5-6 13z" horiz-adv-x="857.1" />
20
+ <glyph glyph-name="cancel-circled" unicode="&#xe80b;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m216-126q0-15 11-26l50-50q10-11 25-11 15 0 26 11l101 101 101-101q10-11 25-11 15 0 25 11l51 50q10 11 10 26 0 14-10 25l-101 101 101 101q10 11 10 25 0 15-10 26l-51 50q-10 11-25 11-15 0-25-11l-101-101-101 101q-11 11-26 11-15 0-25-11l-50-50q-11-11-11-26 0-14 11-25l101-101-101-101q-11-11-11-25z" horiz-adv-x="857.1" />
21
+ </font>
22
+ </defs>
23
+ </svg>
fields/star-rate/fonts/cf-raty.ttf ADDED
Binary file
fields/star-rate/fonts/cf-raty.woff ADDED
Binary file
fields/star-rate/fonts/raty.eot ADDED
Binary file
fields/star-rate/fonts/raty.svg ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>Generated by IcoMoon</metadata>
5
+ <defs>
6
+ <font id="raty" horiz-adv-x="512">
7
+ <font-face units-per-em="512" ascent="480" descent="-32" />
8
+ <missing-glyph horiz-adv-x="512" />
9
+ <glyph unicode="&#x20;" d="" horiz-adv-x="256" />
10
+ <glyph unicode="&#xe600;" d="M256 16c-114.88 0-208 93.12-208 208s93.12 208 208 208 208-93.12 208-208-93.12-208-208-208zM351.376 284.656c3.904 3.904 3.904 10.256 0 14.16l-21.248 21.232c-3.904 3.904-10.256 3.904-14.16 0l-60.176-60.176-60.176 60.176c-3.904 3.904-10.256 3.904-14.16 0l-21.248-21.232c-3.904-3.904-3.904-10.256 0-14.16l60.192-60.192-60.192-60.16c-3.904-3.904-3.904-10.256 0-14.16l21.248-21.248c3.904-3.904 10.256-3.904 14.16 0l60.176 60.192 60.176-60.192c3.904-3.904 10.256-3.904 14.16 0l21.248 21.248c3.904 3.904 3.904 10.256 0 14.16l-60.192 60.16 60.192 60.192z" />
11
+ <glyph unicode="&#xe601;" d="M256 16c-114.88 0-208 93.12-208 208s93.12 208 208 208 208-93.12 208-208-93.12-208-208-208zM256 384c-88.352 0-160-71.648-160-160s71.648-160 160-160c88.368 0 160 71.648 160 160s-71.632 160-160 160zM328.592 167.44l-16.224-16.224c-2.976-2.976-7.808-2.976-10.8 0l-45.92 45.92-45.92-45.92c-2.992-2.976-7.808-2.976-10.8 0l-16.224 16.224c-2.976 2.976-2.976 7.808 0 10.8l45.936 45.904-45.936 45.92c-2.976 2.992-2.976 7.824 0 10.816l16.224 16.208c2.992 2.992 7.808 2.992 10.8 0l45.92-45.92 45.92 45.92c2.992 2.992 7.824 2.992 10.8 0l16.224-16.208c2.976-2.992 2.976-7.824 0-10.816l-45.936-45.92 45.936-45.904c2.976-2.992 2.976-7.84 0-10.8z" />
12
+ <glyph unicode="&#xf005;" d="M475.428 290.572q0-6.286-7.428-13.714l-103.714-101.143 24.572-142.857q0.286-2 0.286-5.714 0-6-3-10.143t-8.714-4.143q-5.428 0-11.428 3.428l-128.286 67.428-128.286-67.428q-6.285-3.428-11.428-3.428-6 0-9 4.143t-3 10.143q0 1.714 0.572 5.714l24.572 142.857-104 101.143q-7.143 7.714-7.143 13.714 0 10.572 16 13.143l143.428 20.857 64.286 130q5.428 11.714 14 11.714t14-11.714l64.286-130 143.429-20.857q16-2.572 16-13.143z" horiz-adv-x="476" />
13
+ <glyph unicode="&#xf006;" d="M324.857 188.572l87.428 84.857-120.572 17.715-54 109.143-54-109.143-120.572-17.714 87.428-84.857-20.857-120.286 108 56.857 107.714-56.857zM475.428 290.572q0-6.286-7.428-13.714l-103.714-101.143 24.572-142.857q0.286-2 0.286-5.714 0-14.286-11.714-14.286-5.428 0-11.428 3.428l-128.286 67.428-128.286-67.428q-6.285-3.428-11.428-3.428-6 0-9 4.143t-3 10.143q0 1.714 0.572 5.714l24.572 142.857-104 101.143q-7.143 7.714-7.143 13.714 0 10.572 16 13.143l143.428 20.857 64.286 130q5.428 11.714 14 11.714t14-11.714l64.286-130 143.429-20.857q16-2.572 16-13.143z" horiz-adv-x="476" />
14
+ <glyph unicode="&#xf123;" d="M338.857 202l73.428 71.428-120.572 17.714-8.572 17.143-45.428 92v-275.143l16.857-8.857 90.857-48-17.143 101.428-3.428 18.857zM468 276.857l-103.714-101.143 24.572-142.857q1.428-9.428-1.714-14.714t-9.714-5.286q-4.857 0-11.428 3.428l-128.286 67.428-128.286-67.428q-6.572-3.428-11.428-3.428-6.572 0-9.715 5.286t-1.715 14.714l24.572 142.857-104 101.143q-9.143 9.143-6.572 17t15.428 9.857l143.429 20.857 64.286 130q5.714 11.714 14 11.714 8 0 14-11.714l64.286-130 143.429-20.857q12.857-2 15.428-9.857t-6.857-17z" horiz-adv-x="476" />
15
+ </font></defs></svg>
fields/star-rate/fonts/raty.ttf ADDED
Binary file
fields/star-rate/fonts/raty.woff ADDED
Binary file
fields/star-rate/images/cancel-off.png ADDED
Binary file
fields/star-rate/images/cancel-on.png ADDED
Binary file
fields/star-rate/images/star-half.png ADDED
Binary file
fields/star-rate/images/star-off.png ADDED
Binary file
fields/star-rate/images/star-on.png ADDED
Binary file
fields/star-rate/jquery.raty.css ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .cancel-on-png, .cancel-off-png, .star-on-png, .star-off-png, .star-half-png {
2
+ font-size: 2em;
3
+ }
4
+
5
+ @font-face {
6
+ font-family: "raty";
7
+ font-style: normal;
8
+ font-weight: normal;
9
+ src: url("fonts/raty.eot");
10
+ src: url("fonts/raty.eot?#iefix") format("embedded-opentype");
11
+ src: url("fonts/raty.svg#raty") format("svg");
12
+ src: url("fonts/raty.ttf") format("truetype");
13
+ src: url("fonts/raty.woff") format("woff");
14
+ }
15
+
16
+ .raty-cancel-on, .raty-cancel-off, .raty-star-on, .raty-star-off, .raty-star-half {
17
+ -moz-osx-font-smoothing: grayscale;
18
+ -webkit-font-smoothing: antialiased;
19
+ font-family: "raty";
20
+ font-style: normal;
21
+ font-variant: normal;
22
+ font-weight: normal;
23
+ line-height: 1;
24
+ speak: none;
25
+ text-transform: none;
26
+ }
27
+
28
+ .raty-cancel-on:before {
29
+ content: "\e600";
30
+ }
31
+
32
+ .raty-cancel-off:before {
33
+ content: "\e601";
34
+ }
35
+
36
+ .raty-star-on:before {
37
+ content: "\f005";
38
+ }
39
+
40
+ .raty-star-off:before {
41
+ content: "\f006";
42
+ }
43
+
44
+ .raty-star-half:before {
45
+ content: "\f123";
46
+ }
fields/star-rate/jquery.raty.js ADDED
@@ -0,0 +1,668 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery Raty - A Star Rating Plugin
3
+ *
4
+ * The MIT License
5
+ *
6
+ * @author : Washington Botelho
7
+ * @doc : http://wbotelhos.com/raty
8
+ * @version : 2.6.0
9
+ *
10
+ */
11
+
12
+ ;(function($) {
13
+ 'use strict';
14
+
15
+ var methods = {
16
+ init: function(options) {
17
+ return this.each(function() {
18
+ this.self = $(this);
19
+
20
+ methods.destroy.call(this.self);
21
+
22
+ this.opt = $.extend(true, {}, $.fn.raty.defaults, options);
23
+
24
+ methods._adjustCallback.call(this);
25
+
26
+ methods._adjustNumber.call(this);
27
+
28
+ if (this.opt.starType !== 'img') {
29
+ methods._adjustStarType.call(this);
30
+ }
31
+
32
+ methods._adjustPath.call(this);
33
+ methods._createStars.call(this);
34
+
35
+ if (this.opt.cancel) {
36
+ methods._createCancel.call(this);
37
+ }
38
+
39
+ if (this.opt.precision) {
40
+ methods._adjustPrecision.call(this);
41
+ }
42
+
43
+ methods._createScore.call(this);
44
+ methods._apply.call(this, this.opt.score);
45
+ methods._target.call(this, this.opt.score);
46
+
47
+ if (this.opt.readOnly) {
48
+ methods._lock.call(this);
49
+ } else {
50
+ this.style.cursor = 'pointer';
51
+
52
+ methods._binds.call(this);
53
+ }
54
+
55
+ this.self.data('options', this.opt);
56
+ });
57
+ },
58
+
59
+ _adjustCallback: function() {
60
+ var options = ['number', 'readOnly', 'score', 'scoreName'];
61
+
62
+ for (var i = 0; i < options.length; i++) {
63
+ if (typeof this.opt[options[i]] === 'function') {
64
+ this.opt[options[i]] = this.opt[options[i]].call(this);
65
+ }
66
+ }
67
+ },
68
+
69
+ _adjustNumber: function() {
70
+ this.opt.number = methods._between(this.opt.number, 1, this.opt.numberMax);
71
+ },
72
+
73
+ _adjustPath: function() {
74
+ this.opt.path = this.opt.path || '';
75
+
76
+ if (this.opt.path && this.opt.path.charAt(this.opt.path.length - 1) !== '/') {
77
+ this.opt.path += '/';
78
+ }
79
+ },
80
+
81
+ _adjustPrecision: function() {
82
+ this.opt.half = true;
83
+ this.opt.targetType = 'score';
84
+ },
85
+
86
+ _adjustStarType: function() {
87
+ this.opt.path = '';
88
+
89
+ var replaces = ['cancelOff', 'cancelOn', 'starHalf', 'starOff', 'starOn'];
90
+
91
+ for (var i = 0; i < replaces.length; i++) {
92
+ this.opt[replaces[i]] = this.opt[replaces[i]].replace('.', '-');
93
+ }
94
+ },
95
+
96
+ _apply: function(score) {
97
+ methods._fill.call(this, score);
98
+
99
+ if (score) {
100
+ if (score > 0) {
101
+ this.score.val(methods._between(score, 0, this.opt.number));
102
+ }
103
+
104
+ methods._roundStars.call(this, score);
105
+ }
106
+ },
107
+
108
+ _between: function(value, min, max) {
109
+ return Math.min(Math.max(parseFloat(value), min), max);
110
+ },
111
+
112
+ _binds: function() {
113
+ if (this.cancel) {
114
+ methods._bindOverCancel.call(this);
115
+ methods._bindClickCancel.call(this);
116
+ methods._bindOutCancel.call(this);
117
+ }
118
+
119
+ methods._bindOver.call(this);
120
+ methods._bindClick.call(this);
121
+ methods._bindOut.call(this);
122
+ },
123
+
124
+ _bindClick: function() {
125
+ var that = this;
126
+
127
+ that.stars.on('click.raty', function(evt) {
128
+ var star = $(this);
129
+
130
+ that.score.val((that.opt.half || that.opt.precision) ? that.self.data('score') : (this.alt || star.data('alt')));
131
+
132
+ if (that.opt.click) {
133
+ that.opt.click.call(that, +that.score.val(), evt);
134
+ }
135
+ });
136
+ },
137
+
138
+ _bindClickCancel: function() {
139
+ var that = this;
140
+
141
+ that.cancel.on('click.raty', function(evt) {
142
+ that.score.removeAttr('value');
143
+
144
+ if (that.opt.click) {
145
+ that.opt.click.call(that, null, evt);
146
+ }
147
+ });
148
+ },
149
+
150
+ _bindOut: function() {
151
+ var that = this;
152
+
153
+ that.self.on('mouseleave.raty', function(evt) {
154
+ var score = +that.score.val() || undefined;
155
+
156
+ methods._apply.call(that, score);
157
+ methods._target.call(that, score, evt);
158
+
159
+ if (that.opt.mouseout) {
160
+ that.opt.mouseout.call(that, score, evt);
161
+ }
162
+ });
163
+ },
164
+
165
+ _bindOutCancel: function() {
166
+ var that = this;
167
+
168
+ that.cancel.on('mouseleave.raty', function(evt) {
169
+ var
170
+ cancel = $(this),
171
+ cancelOff = that.opt.path + that.opt.cancelOff;
172
+
173
+ if (that.opt.starType === 'img') {
174
+ cancel.attr('src', cancelOff);
175
+ } else {
176
+ var cancelOn = that.opt.path + that.opt.cancelOn;
177
+
178
+ cancel.removeClass(cancelOn).addClass(cancelOff);
179
+ }
180
+
181
+ if (that.opt.mouseout) {
182
+ var score = +that.score.val() || undefined;
183
+
184
+ that.opt.mouseout.call(that, score, evt);
185
+ }
186
+ });
187
+ },
188
+
189
+ _bindOver: function() {
190
+ var that = this,
191
+ action = that.opt.half ? 'mousemove.raty' : 'mouseover.raty';
192
+
193
+ that.stars.on(action, function(evt) {
194
+ var score = methods._getScoreByPosition.call(that, evt, this);
195
+
196
+ methods._fill.call(that, score);
197
+
198
+ if (that.opt.half) {
199
+ methods._roundStars.call(that, score);
200
+
201
+ that.self.data('score', score);
202
+ }
203
+
204
+ methods._target.call(that, score, evt);
205
+
206
+ if (that.opt.mouseover) {
207
+ that.opt.mouseover.call(that, score, evt);
208
+ }
209
+ });
210
+ },
211
+
212
+ _bindOverCancel: function() {
213
+ var that = this;
214
+
215
+ that.cancel.on('mouseover.raty', function(evt) {
216
+ var
217
+ cancelOn = that.opt.path + that.opt.cancelOn,
218
+ star = $(this),
219
+ starOff = that.opt.path + that.opt.starOff;
220
+
221
+ if (that.opt.starType === 'img') {
222
+ star.attr('src', cancelOn);
223
+ that.stars.attr('src', starOff);
224
+ } else {
225
+ that.stars.attr('class', starOff);
226
+
227
+ var cancelOff = that.opt.path + that.opt.cancelOff;
228
+
229
+ star.removeClass(cancelOff).addClass(cancelOn).css('color', that.opt.starColor);
230
+ }
231
+
232
+ methods._target.call(that, null, evt);
233
+
234
+ if (that.opt.mouseover) {
235
+ that.opt.mouseover.call(that, null);
236
+ }
237
+ });
238
+ },
239
+
240
+ _buildScoreField: function() {
241
+ return $('<input />', { name: this.opt.scoreName, type: 'hidden' }).appendTo(this);
242
+ },
243
+
244
+ _createCancel: function() {
245
+ var icon = this.opt.path + this.opt.cancelOff,
246
+ cancel = $('<' + this.opt.starType + ' />', { title: this.opt.cancelHint, 'class': 'raty-cancel' }).css('marginRight', this.opt.space ? this.opt.spaceWidth + 'px' : '0');
247
+
248
+ if (this.opt.starType === 'img') {
249
+ cancel.attr({ src: icon, alt: 'x' });
250
+ } else {
251
+ // TODO: use $.data
252
+ cancel.attr('data-alt', 'x').addClass(icon);
253
+ }
254
+
255
+ if (this.opt.cancelPlace === 'left') {
256
+ this.self.prepend('&#160;').prepend(cancel);
257
+ } else {
258
+ this.self.append('&#160;').append(cancel);
259
+ }
260
+
261
+ this.cancel = cancel;
262
+ },
263
+
264
+ _createScore: function() {
265
+ var score = $(this.opt.targetScore);
266
+
267
+ this.score = score.length ? score : methods._buildScoreField.call(this);
268
+ },
269
+
270
+ _createStars: function() {
271
+ for (var i = 1; i <= this.opt.number; i++) {
272
+ var
273
+ attrs ,
274
+ icon = (this.opt.score && this.opt.score >= i) ? 'starOn' : 'starOff',
275
+ title = methods._getHint.call(this, i);
276
+
277
+ // TODO: extract as icon: && alt:
278
+ icon = this.opt.path + this.opt[icon];
279
+
280
+ if (this.opt.starType !== 'img') {
281
+ // TODO: use $.data.
282
+ attrs = { 'data-alt': i, 'class': icon };
283
+ } else {
284
+ attrs = { src: icon, alt: i };
285
+ }
286
+
287
+ attrs.title = title;
288
+
289
+ $('<' + this.opt.starType + ' />', attrs).css('marginRight', i < this.opt.number && this.opt.space ? this.opt.spaceWidth + 'px' : '0').appendTo(this);
290
+
291
+ if (this.opt.space) {
292
+ // this.self.append(i < this.opt.number ? '&#160;' : '');
293
+ }
294
+ }
295
+
296
+ this.stars = this.self.children(this.opt.starType);
297
+ },
298
+
299
+ _error: function(message) {
300
+ $(this).text(message);
301
+
302
+ $.error(message);
303
+ },
304
+
305
+ _fill: function(score) {
306
+ var hash = 0;
307
+
308
+ for (var i = 1; i <= this.stars.length; i++) {
309
+ var
310
+ icon,
311
+ star = this.stars.eq(i - 1),
312
+ turnOn = methods._turnOn.call(this, i, score);
313
+
314
+ if (this.opt.iconRange && this.opt.iconRange.length > hash) {
315
+ var irange = this.opt.iconRange[hash];
316
+
317
+ icon = methods._getIconRange.call(this, irange, turnOn);
318
+
319
+ if (i <= irange.range) {
320
+ // TODO: extract.
321
+ if (this.opt.starType === 'img') {
322
+ star.attr('src', icon);
323
+ } else {
324
+ star.attr('class', icon);
325
+ }
326
+ }
327
+
328
+ if (i === irange.range) {
329
+ hash++;
330
+ }
331
+ } else {
332
+ icon = this.opt.path + this.opt[turnOn ? 'starOn' : 'starOff'];
333
+ // TODO: extract.
334
+ if (this.opt.starType === 'img') {
335
+ star.attr('src', icon);
336
+ } else {
337
+ star.attr('class', icon);
338
+ }
339
+ // Set Color
340
+ if (turnOn) {
341
+ star.css('color', this.opt.starColor);
342
+ }else{
343
+ star.css('color', '');
344
+ }
345
+ }
346
+ }
347
+ },
348
+
349
+ _getIconRange: function(irange, turnOn) {
350
+ return this.opt.path + (turnOn ? irange.on || this.opt.starOn : irange.off || this.opt.starOff);
351
+ },
352
+
353
+ _getScoreByPosition: function(evt, icon) {
354
+ var
355
+ star = $(icon),
356
+ score = parseInt(icon.alt || star.data('alt'), 10);
357
+
358
+ if (this.opt.half) {
359
+ var
360
+ size = methods._getSize.call(this),
361
+ percent = parseFloat((evt.pageX - star.offset().left) / size);
362
+
363
+ if (this.opt.precision) {
364
+ score = score - 1 + percent;
365
+ } else {
366
+ score = score - 1 + (percent > 0.5 ? 1 : 0.5);
367
+ }
368
+ }
369
+
370
+
371
+ return score;
372
+ },
373
+
374
+ _getSize: function() {
375
+ var size;
376
+
377
+ if (this.opt.starType === 'img') {
378
+ size = this.stars[0].width;
379
+ } else {
380
+ size = parseFloat(this.stars.eq(0).css('font-size'));
381
+ }
382
+
383
+ if (!size) {
384
+ methods._error.call(this, 'Could not be possible get the icon size!');
385
+ }
386
+
387
+ return size;
388
+ },
389
+
390
+ _turnOn: function(i, score) {
391
+ return this.opt.single ? (i === score) : (i <= score);
392
+ },
393
+
394
+ _getHint: function(score) {
395
+ var hint = this.opt.hints[score - 1];
396
+
397
+ return hint === '' ? '' : hint || score;
398
+ },
399
+
400
+ _lock: function() {
401
+ var score = parseInt(this.score.val(), 10), // TODO: 3.1 >> [['1'], ['2'], ['3', '.1', '.2']]
402
+ hint = score ? methods._getHint.call(this, score) : this.opt.noRatedMsg;
403
+
404
+ this.style.cursor = '';
405
+ this.title = hint;
406
+
407
+ this.score.prop('readonly', true);
408
+ this.stars.prop('title', hint);
409
+
410
+ if (this.cancel) {
411
+ this.cancel.hide();
412
+ }
413
+
414
+ this.self.data('readonly', true);
415
+ },
416
+
417
+ _roundStars: function(score) {
418
+ var rest = (score % 1).toFixed(2);
419
+
420
+ if (rest > this.opt.round.down) { // Up: [x.76 .. x.99]
421
+ var icon = 'starOn';
422
+
423
+ if (this.opt.halfShow && rest < this.opt.round.up) { // Half: [x.26 .. x.75]
424
+ icon = 'starHalf';
425
+ } else if (rest < this.opt.round.full) { // Down: [x.00 .. x.5]
426
+ icon = 'starOff';
427
+ }
428
+
429
+ var star = this.stars[Math.ceil(score) - 1];
430
+
431
+ if (this.opt.starType === 'img') {
432
+ star.src = this.opt.path + this.opt[icon];
433
+ } else {
434
+ star.style.className = this.opt[icon];
435
+ }
436
+ } // Full down: [x.00 .. x.25]
437
+ },
438
+
439
+ _target: function(score, evt) {
440
+ if (this.opt.target) {
441
+ var target = $(this.opt.target);
442
+
443
+ if (!target.length) {
444
+ methods._error.call(this, 'Target selector invalid or missing!');
445
+ }
446
+
447
+ var mouseover = evt && evt.type === 'mouseover';
448
+
449
+ if (score === undefined) {
450
+ score = this.opt.targetText;
451
+ } else if (score === null) {
452
+ score = mouseover ? this.opt.cancelHint : this.opt.targetText;
453
+ } else {
454
+ if (this.opt.targetType === 'hint') {
455
+ score = methods._getHint.call(this, Math.ceil(score));
456
+ } else if (this.opt.precision) {
457
+ score = parseFloat(score).toFixed(1);
458
+ }
459
+
460
+ var mousemove = evt && evt.type === 'mousemove';
461
+
462
+ if (!mouseover && !mousemove && !this.opt.targetKeep) {
463
+ score = this.opt.targetText;
464
+ }
465
+ }
466
+
467
+ if (score) {
468
+ score = this.opt.targetFormat.toString().replace('{score}', score);
469
+ }
470
+
471
+ if (target.is(':input')) {
472
+ target.val(score);
473
+ } else {
474
+ target.html(score);
475
+ }
476
+ }
477
+ },
478
+
479
+ _unlock: function() {
480
+ this.style.cursor = 'pointer';
481
+ this.removeAttribute('title');
482
+
483
+ this.score.removeAttr('readonly');
484
+
485
+ this.self.data('readonly', false);
486
+
487
+ for (var i = 0; i < this.opt.number; i++) {
488
+ this.stars[i].title = methods._getHint.call(this, i + 1);
489
+ }
490
+
491
+ if (this.cancel) {
492
+ this.cancel.css('display', '');
493
+ }
494
+ },
495
+
496
+ cancel: function(click) {
497
+ return this.each(function() {
498
+ var el = $(this);
499
+
500
+ if (el.data('readonly') !== true) {
501
+ methods[click ? 'click' : 'score'].call(el, null);
502
+
503
+ this.score.removeAttr('value');
504
+ }
505
+ });
506
+ },
507
+
508
+ click: function(score) {
509
+ return this.each(function() {
510
+ if ($(this).data('readonly') !== true) {
511
+ methods._apply.call(this, score);
512
+
513
+ if (this.opt.click) {
514
+ this.opt.click.call(this, score, $.Event('click'));
515
+ }
516
+
517
+ methods._target.call(this, score);
518
+ }
519
+ });
520
+ },
521
+
522
+ destroy: function() {
523
+ return this.each(function() {
524
+ var self = $(this),
525
+ raw = self.data('raw');
526
+
527
+ if (raw) {
528
+ self.off('.raty').empty().css({ cursor: raw.style.cursor }).removeData('readonly');
529
+ } else {
530
+ self.data('raw', self.clone()[0]);
531
+ }
532
+ });
533
+ },
534
+
535
+ getScore: function() {
536
+ var score = [],
537
+ value ;
538
+
539
+ this.each(function() {
540
+ value = this.score.val();
541
+
542
+ score.push(value ? +value : undefined);
543
+ });
544
+
545
+ return (score.length > 1) ? score : score[0];
546
+ },
547
+
548
+ move: function(score) {
549
+ return this.each(function() {
550
+ var
551
+ integer = parseInt(score, 10),
552
+ opt = $(this).data('options'),
553
+ decimal = (+score).toFixed(1).split('.')[1];
554
+
555
+ if (integer >= opt.number) {
556
+ integer = opt.number - 1;
557
+ decimal = 10;
558
+ }
559
+
560
+ var
561
+ size = methods._getSize.call(this),
562
+ point = size / 10,
563
+ star = $(this.stars[integer]),
564
+ percent = star.offset().left + point * parseInt(decimal, 10),
565
+ evt = $.Event('mousemove', { pageX: percent });
566
+
567
+ star.trigger(evt);
568
+ });
569
+ },
570
+
571
+ readOnly: function(readonly) {
572
+ return this.each(function() {
573
+ var self = $(this);
574
+
575
+ if (self.data('readonly') !== readonly) {
576
+ if (readonly) {
577
+ self.off('.raty').children('img').off('.raty');
578
+
579
+ methods._lock.call(this);
580
+ } else {
581
+ methods._binds.call(this);
582
+ methods._unlock.call(this);
583
+ }
584
+
585
+ self.data('readonly', readonly);
586
+ }
587
+ });
588
+ },
589
+
590
+ reload: function() {
591
+ return methods.set.call(this, {});
592
+ },
593
+
594
+ score: function() {
595
+ var self = $(this);
596
+
597
+ return arguments.length ? methods.setScore.apply(self, arguments) : methods.getScore.call(self);
598
+ },
599
+
600
+ set: function(options) {
601
+ return this.each(function() {
602
+ var self = $(this),
603
+ actual = self.data('options'),
604
+ news = $.extend({}, actual, options);
605
+
606
+ self.raty(news);
607
+ });
608
+ },
609
+
610
+ setScore: function(score) {
611
+ return this.each(function() {
612
+ if ($(this).data('readonly') !== true) {
613
+ methods._apply.call(this, score);
614
+ methods._target.call(this, score);
615
+ }
616
+ });
617
+ }
618
+ };
619
+
620
+ $.fn.raty = function(method) {
621
+ if (methods[method]) {
622
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
623
+ } else if (typeof method === 'object' || !method) {
624
+ return methods.init.apply(this, arguments);
625
+ } else {
626
+ $.error('Method ' + method + ' does not exist!');
627
+ }
628
+ };
629
+
630
+ $.fn.raty.defaults = {
631
+ cancel : false,
632
+ cancelHint : 'Cancel this rating!',
633
+ cancelOff : 'raty-cancel-off',
634
+ cancelOn : 'raty-cancel-on',
635
+ cancelPlace : 'left',
636
+ click : undefined,
637
+ half : false,
638
+ halfShow : true,
639
+ hints : ['1'],
640
+ iconRange : undefined,
641
+ mouseout : undefined,
642
+ mouseover : undefined,
643
+ noRatedMsg : 'Not rated yet!',
644
+ number : 5,
645
+ numberMax : 20,
646
+ path : undefined,
647
+ precision : false,
648
+ readOnly : false,
649
+ round : { down: 0.25, full: 0.6, up: 0.76 },
650
+ score : undefined,
651
+ scoreName : 'score',
652
+ single : false,
653
+ space : true,
654
+ spaceWidth : 3,
655
+ starColor : '#ff00aa',
656
+ starHalf : 'star-half.png',
657
+ starOff : 'raty-dot-off',
658
+ starOn : 'raty-dot-on',
659
+ starType : 'img',
660
+ target : undefined,
661
+ targetFormat : '{score}',
662
+ targetKeep : false,
663
+ targetScore : undefined,
664
+ targetText : '',
665
+ targetType : 'hint'
666
+ };
667
+
668
+ })(jQuery);
fields/star-rate/preview.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="preview-caldera-config-group">
2
+ {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
+ <div class="preview-caldera-config-field">
4
+ <div id="{{id}}_stars_preview" style="color:{{config/track_color}};font-size:{{config/size}}px;"></div>
5
+ <span class="help-block">{{caption}}</span>
6
+ </div>
7
+ </div>
8
+ {{#script}}
9
+ jQuery('#{{id}}_stars_preview').raty({
10
+ starOff : 'raty-{{config/type}}-off',
11
+ starOn : 'raty-{{config/type}}-on',
12
+ hints: [1,2,3,4,5],
13
+ spaceWidth: {{config/space}},
14
+ number: {{config/number}},
15
+ starType: 'f',
16
+ starColor: '{{config/color}}',
17
+ trackColor: '{{config/track_color}}',
18
+ numberMax: 100
19
+ {{#if config/cancel}},cancel: true{{/if}}
20
+ {{#if config/single}},single: true{{/if}}
21
+ });
22
+ {{/script}}
fields/text/config.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="caldera-config-group">
2
+ <label>Placeholder</label>
3
+ <div class="caldera-config-field">
4
+ <input type="text" id="{{_id}}_placeholder" class="block-input field-config" name="{{_name}}[placeholder]" value="{{placeholder}}">
5
+ </div>
6
+ </div>
7
+ <div class="caldera-config-group">
8
+ <label>Default</label>
9
+ <div class="caldera-config-field">
10
+ <input type="text" id="{{_id}}_default" class="block-input field-config" name="{{_name}}[default]" value="{{default}}">
11
+ </div>
12
+ </div>
13
+
14
+ <div class="caldera-config-group">
15
+ <label>Masked Input</label>
16
+ <div class="caldera-config-field">
17
+ <label><input type="checkbox" class="field-config {{_id}}_masked" name="{{_name}}[masked]" value="1" {{#if masked}}checked="checked"{{/if}}> Enable input mask</label>
18
+ </div>
19
+ </div>
20
+ <div class="caldera-config-group" id="{{_id}}_maskwrap">
21
+ <label>Mask</label>
22
+ <div class="caldera-config-field">
23
+ <input type="text" id="{{_id}}_mask" class="block-input field-config" name="{{_name}}[mask]" value="{{mask}}">
24
+ </div>
25
+ <p class="description">e.g (aaa-99-999-a9-9*)</p>
26
+ <ul>
27
+ <li>9 : numeric</li>
28
+ <li>a : alphabetical</li>
29
+ <li>* : alphanumeric</li>
30
+ </ul>
31
+ </div>
32
+
33
+ {{#script}}
34
+ jQuery(function($){
35
+
36
+ $('.{{_id}}_masked').change(function(){
37
+ if( $(this).prop('checked') ){
38
+ $('#{{_id}}_maskwrap').show();
39
+ $('#{{_id}}_default').inputmask($('#{{_id}}_mask').val());
40
+ }else{
41
+ $('#{{_id}}_maskwrap').hide();
42
+ $('#{{_id}}_default').inputmask("");
43
+ }
44
+ });
45
+ $('#{{_id}}_mask').change(function(){
46
+ $('.{{_id}}_masked').trigger('change');
47
+ });
48
+ $('.{{_id}}_masked').trigger('change');
49
+ });
50
+ {{/script}}
fields/text/config_template.html DELETED
@@ -1,6 +0,0 @@
1
- <div class="caldera-config-group">
2
- <label>Default</label>
3
- <div class="caldera-config-field">
4
- <input type="text" class="block-input field-config" name="{{_name}}[default]" value="{{default}}">
5
- </div>
6
- </div>
 
 
 
 
 
 
fields/text/field.php CHANGED
@@ -1,7 +1,17 @@
1
- <div class="<?php echo $field_wrapper_class; ?>">
 
 
 
 
 
 
 
 
 
 
2
  <?php echo $field_label; ?>
3
  <div class="<?php echo $field_input_class; ?>">
4
- <input <?php echo $field_placeholder; ?> type="text" data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" id="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo htmlentities( $field_value ); ?>" <?php echo $field_required; ?>>
5
  <?php echo $field_caption; ?>
6
  </div>
7
- </div>
1
+ <?php
2
+ if(!empty($field['config']['placeholder'])){
3
+ $field_placeholder = 'placeholder="'.$field['config']['placeholder'].'"';
4
+ }
5
+
6
+ $mask = null;
7
+ if(!empty($field['config']['masked'])){
8
+ $mask = "data-inputmask=\"'mask': '".$field['config']['mask']."'\" ";
9
+ }
10
+
11
+ ?><div class="<?php echo $field_wrapper_class; ?>">
12
  <?php echo $field_label; ?>
13
  <div class="<?php echo $field_input_class; ?>">
14
+ <input <?php echo $field_placeholder; ?> type="text"<?php echo $mask; ?> data-field="<?php echo $field_base_id; ?>" class="<?php echo $field_class; ?>" id="<?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo htmlentities( $field_value ); ?>" <?php echo $field_required; ?>>
15
  <?php echo $field_caption; ?>
16
  </div>
17
+ </div>
fields/text/preview.php CHANGED
@@ -1,7 +1,7 @@
1
  <div class="preview-caldera-config-group">
2
  {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
  <div class="preview-caldera-config-field">
4
- <input {{#if hide_label}}placeholder="{{label}}"{{/if}} type="text" class="preview-field-config" value="{{config/default}}">
5
  <span class="help-block">{{caption}}</span>
6
  </div>
7
  </div>
1
  <div class="preview-caldera-config-group">
2
  {{#unless hide_label}}<lable class="control-label">{{label}}{{#if required}} <span style="color:#ff0000;">*</span>{{/if}}</lable>{{/unless}}
3
  <div class="preview-caldera-config-field">
4
+ <input {{#if hide_label}}placeholder="{{label}}"{{else}}placeholder="{{config/placeholder}}"{{/if}} type="text" class="preview-field-config" value="{{config/default}}">
5
  <span class="help-block">{{caption}}</span>
6
  </div>
7
  </div>
fields/toggle_switch/css/setup.css CHANGED
@@ -3,7 +3,7 @@
3
  }
4
 
5
  .toggle_option_row input{
6
- display: inline;
7
  }
8
 
9
  .toggle_option_row .dashicons-sort{ cursor: move;}
3
  }
4
 
5
  .toggle_option_row input{
6
+ display: inline-block;
7
  }
8
 
9
  .toggle_option_row .dashicons-sort{ cursor: move;}
fields/toggle_switch/field.php CHANGED
@@ -9,6 +9,10 @@
9
 
10
  <?php }else{
11
  foreach($field['config']['option'] as $option_key=>$option){
 
 
 
 
12
  ?><button type="button" id="<?php echo $field_id.'_'.$option_key; ?>" class="btn btn-default" data-value="<?php echo $option['value']; ?>"><?php echo $option['label']; ?></button><?php
13
  }
14
  } ?>
@@ -17,6 +21,10 @@
17
  <?php
18
  if(!empty($field['config']['option'])){
19
  foreach($field['config']['option'] as $option_key=>$option){
 
 
 
 
20
  ?>
21
  <input type="radio" id="<?php echo $field_id . '_' . $option_key; ?>" data-field="<?php echo $field_base_id; ?>" data-ref="<?php echo $field_id.'_'.$option_key; ?>" class="cf-toggle-group-radio <?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo $option['value']; ?>" {{#if <?php echo $field['slug'].'_'.$option['value']; ?>}}checked="true"{{/if}}>
22
  <?php
9
 
10
  <?php }else{
11
  foreach($field['config']['option'] as $option_key=>$option){
12
+ if(!isset($option['value'])){
13
+ $option['value'] = htmlspecialchars( $option['label'] );
14
+ }
15
+
16
  ?><button type="button" id="<?php echo $field_id.'_'.$option_key; ?>" class="btn btn-default" data-value="<?php echo $option['value']; ?>"><?php echo $option['label']; ?></button><?php
17
  }
18
  } ?>
21
  <?php
22
  if(!empty($field['config']['option'])){
23
  foreach($field['config']['option'] as $option_key=>$option){
24
+ if(!isset($option['value'])){
25
+ $option['value'] = htmlspecialchars( $option['label'] );
26
+ }
27
+
28
  ?>
29
  <input type="radio" id="<?php echo $field_id . '_' . $option_key; ?>" data-field="<?php echo $field_base_id; ?>" data-ref="<?php echo $field_id.'_'.$option_key; ?>" class="cf-toggle-group-radio <?php echo $field_id; ?>" name="<?php echo $field_name; ?>" value="<?php echo $option['value']; ?>" {{#if <?php echo $field['slug'].'_'.$option['value']; ?>}}checked="true"{{/if}}>
30
  <?php
fields/toggle_switch/js/toggle.js CHANGED
@@ -6,8 +6,8 @@ jQuery(function($){
6
  input = parent.find('[data-ref="'+clicked.attr('id')+'"]');
7
 
8
 
9
- parent.find('.btn').removeClass('btn-primary').addClass('btn-default');
10
- clicked.addClass('btn-primary').removeClass('btn-default');
11
  input.prop('checked', true).trigger('change');
12
  });
13
  });
6
  input = parent.find('[data-ref="'+clicked.attr('id')+'"]');
7
 
8
 
9
+ parent.find('.btn').removeClass('btn-success').addClass('btn-default');
10
+ clicked.addClass('btn-success').removeClass('btn-default');
11
  input.prop('checked', true).trigger('change');
12
  });
13
  });
includes/cf-ajax/js/ajax-core.js ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var resBaldrickTriggers;
2
+
3
+ jQuery(function($){
4
+
5
+ // admin stuff!
6
+ // Baldrick Bindings
7
+ resBaldrickTriggers = function(){
8
+ $('.cfajax-trigger').baldrick({
9
+ request : './',
10
+ method : 'POST',
11
+ before : function(el){
12
+
13
+ var target = $($(el).data('target')),
14
+ spinner = target.data('spinner'),
15
+ buttons = $(el).find(':submit');
16
+ buttons.prop('disabled',true).after('<img class="caldera_forms_ajax_spinner" src="' + spinner + '" style="margin: 5px;">');
17
+
18
+ },
19
+ callback : function(obj){
20
+
21
+ obj.params.trigger.find(':submit').prop('disabled',false);
22
+
23
+ $('.caldera_forms_ajax_spinner').remove();
24
+ $('.caldera_ajax_error_wrap').removeClass('caldera_ajax_error_wrap').removeClass('has-error');
25
+ $('.caldera_ajax_error_block').remove();
26
+
27
+ if(obj.data.status === 'complete'){
28
+ if(obj.data.html){
29
+ obj.params.target.html(obj.data.html);
30
+ }
31
+ if(!obj.data.entry){
32
+ obj.params.trigger[0].reset();
33
+ }
34
+ if(obj.params.trigger.data('hiderows')){
35
+ obj.params.trigger.find('div.row').remove();
36
+ }
37
+ }else if(obj.data.status === 'preprocess'){
38
+ obj.params.target.html(obj.data.html);
39
+ }else if(obj.data.status === 'error'){
40
+ obj.params.target.html(obj.data.html);
41
+ }
42
+ // do a redirect if set
43
+ if(obj.data.url){
44
+ window.location = obj.data.url;
45
+ }
46
+
47
+ if(obj.data.fields){
48
+ for(var i in obj.data.fields){
49
+ var field = $('[data-field="' + i + '"]'),
50
+ wrap = field.closest('.form-group');
51
+
52
+ wrap.addClass('has-error').addClass('caldera_ajax_error_wrap');
53
+ wrap.append('<span class="help-block caldera_ajax_error_block">' + obj.data.fields[i] + '</span>');
54
+ }
55
+ }
56
+ }
57
+ });
58
+ };
59
+
60
+ resBaldrickTriggers();
61
+ });
includes/cf-ajax/plugin.php ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Ajax Submissions addon- included
4
+ */
5
+
6
+ //add_filter('caldera_forms_render_grid_structure', 'cf_ajax_structures', 10, 2);
7
+ add_action('caldera_forms_redirect', 'cf_ajax_redirect', 10, 5);
8
+ add_filter('caldera_forms_render_form_classes', 'cf_ajax_register_scripts', 10, 2);
9
+ add_action('caldera_forms_general_settings_panel', 'cf_form_ajaxsetup');
10
+
11
+ function cf_form_ajaxsetup($form){
12
+ ?>
13
+ <div class="caldera-config-group">
14
+ <label><?php echo __('Ajax Submissions', 'caldera-forms'); ?></label>
15
+ <div class="caldera-config-field">
16
+ <label><input type="checkbox" value="1" name="config[form_ajax]" class="field-config"<?php if(isset($form['form_ajax'])){ echo ' checked="checked"'; } ?>> <?php echo __('Enable Ajax Submissions. (No page reloads)', 'caldera-forms'); ?></label>
17
+ </div>
18
+ </div>
19
+ <?php
20
+ }
21
+
22
+ /*function cf_ajax_structures($grid, $form){
23
+
24
+ if(empty($form['form_ajax'])){
25
+ return $grid;
26
+ }
27
+ global $current_form_count;
28
+
29
+ // add in notification area
30
+ $grid->before('<div id="caldera_notices_'.$current_form_count.'" data-spinner="'. admin_url( 'images/spinner.gif' ).'"></div>', '1', 'prepend');
31
+
32
+ return $grid;
33
+ }*/
34
+
35
+ function cf_ajax_redirect($type, $url, $form){
36
+
37
+ if(empty($form['form_ajax'])){
38
+ return;
39
+ }
40
+
41
+ if( empty( $_POST['cfajax'] ) ){
42
+ return;
43
+ }
44
+
45
+ $data = Caldera_Forms::get_submission_data($form);
46
+
47
+ // setup notcies
48
+ $urlparts = parse_url($url);
49
+ $query = array();
50
+
51
+ if(!empty($urlparts['query'])){
52
+ parse_str($urlparts['query'], $query);
53
+ }
54
+
55
+ $notices = array();
56
+ $note_general_classes = array(
57
+ 'alert'
58
+ );
59
+ $note_general_classes = apply_filters('caldera_forms_render_note_general_classes', $note_general_classes, $form);
60
+
61
+ // base id
62
+ $form_id = 'caldera_form_1';
63
+
64
+ if($type == 'complete'){
65
+ if(isset($query['cf_su'])){
66
+ $notices['success']['note'] = $form['success'];
67
+ $form_id = 'caldera_form_' . $query['cf_su'];
68
+ }else{
69
+ $out['url'] = $url;
70
+ $notices['success']['note'] = __('Redirecting');
71
+ }
72
+ }elseif($type == 'preprocess'){
73
+ if(isset($query['cf_er'])){
74
+ $data = get_transient( $query['cf_er'] );
75
+ if(!empty($data['note'])){
76
+ $notices[$data['type']]['note'] = $data['note'];
77
+ }
78
+ if(!empty($data['fields'])){
79
+ foreach($form['fields'] as $fieldid=>$field){
80
+ if( isset( $data['fields'][$fieldid] ) ){
81
+ $out['fields'][$fieldid] = $data['fields'][$fieldid];
82
+ }
83
+ }
84
+ }
85
+ }else{
86
+ $out['url'] = $url;
87
+ $notices['success']['note'] = __('Redirecting');
88
+ }
89
+
90
+ }elseif($type == 'error'){
91
+ $data = get_transient( $query['cf_er'] );
92
+ if(!empty($data['note'])){
93
+ $notices['error']['note'] = $data['note'];
94
+ }
95
+
96
+ if(!empty($data['fields'])){
97
+
98
+ foreach($form['fields'] as $fieldid=>$field){
99
+ if( isset( $data['fields'][$fieldid] ) ){
100
+ $out['fields'][$fieldid] = $data['fields'][$fieldid];
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ $notices = apply_filters('caldera_forms_render_notices', $notices, $form);
107
+
108
+ $note_classes = array(
109
+ 'success' => array_merge($note_general_classes, array(
110
+ 'alert-success'
111
+ )),
112
+ 'error' => array_merge($note_general_classes, array(
113
+ 'alert-error'
114
+ )),
115
+ 'info' => array_merge($note_general_classes, array(
116
+ 'alert-info'
117
+ )),
118
+ 'warning' => array_merge($note_general_classes, array(
119
+ 'alert-warning'
120
+ )),
121
+ 'danger' => array_merge($note_general_classes, array(
122
+ 'alert-danger'
123
+ )),
124
+ );
125
+
126
+ $note_classes = apply_filters('caldera_forms_render_note_classes', $note_classes, $form);
127
+
128
+ $html = '';
129
+
130
+ if(!empty($notices)){
131
+ // do notices
132
+ foreach($notices as $note_type => $notice){
133
+ if(!empty($notice['note'])){
134
+ $html .= '<div class=" '. implode(' ', $note_classes[$note_type]) . '">' . $notice['note'] .'</div>';
135
+ }
136
+ }
137
+
138
+ }
139
+ $out['html'] = $html;
140
+ $out['status'] = $type;
141
+
142
+ $out = apply_filters('caldera_forms_ajax_return', $out, $form);
143
+
144
+ header('Content-Type: application/json');
145
+ echo json_encode( $out );
146
+ exit;
147
+
148
+ }
149
+
150
+ function cf_ajax_register_scripts($classes, $form){
151
+ if(empty($form['form_ajax'])){
152
+ return $classes;
153
+ }
154
+ // setup attributes action
155
+ add_filter('caldera_forms_render_form_attributes', 'cf_ajax_setatts', 10, 2);
156
+
157
+ // enqueue scripts
158
+ wp_enqueue_script( 'jquery' );
159
+ wp_enqueue_script( 'cfajax-baldrick', CFCORE_URL . 'assets/js/jquery.baldrick.js', array('jquery'), '1.00', true );
160
+ wp_enqueue_script( 'cfajax-core', plugin_dir_url(__FILE__) . 'js/ajax-core.js', array('cfajax-baldrick'), '1.00', true );
161
+
162
+ $classes[] = 'cfajax-trigger';
163
+
164
+ return $classes;
165
+ }
166
+
167
+ function cf_ajax_setatts($atts, $form){
168
+ global $current_form_count;
169
+
170
+ $resatts = array(
171
+ 'data-target' => '#caldera_notices_'.$current_form_count,
172
+ 'data-template' => '#cfajax_'.$form['ID'].'-tmpl',
173
+ 'data-cfajax' => $form['ID']
174
+ );
175
+ if(!empty($form['hide_form'])){
176
+ $resatts['data-hiderows'] = "true";
177
+ }
178
+
179
+ return array_merge($atts, $resatts);
180
+
181
+ }
includes/custom_field_class.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+
6
+ add_action('caldera_forms_field_settings_template', 'cf_custom_field_classes');
7
+ add_filter('caldera_forms_render_field_classes', 'cf_apply_field_classes', 10, 3);
8
+
9
+
10
+ function cf_apply_field_classes($classes, $field, $form){
11
+
12
+ if(!empty($field['config']['custom_class'])){
13
+ $classes['control_wrapper'] .= ' '.$field['config']['custom_class'];
14
+ }
15
+ return $classes;
16
+ }
17
+
18
+ function cf_custom_field_classes(){
19
+ ?>
20
+ <div class="caldera-config-group">
21
+ <label><?php echo __('Custom Class', 'caldera-forms'); ?> </label>
22
+ <div class="caldera-config-field">
23
+ <input type="text" class="block-input field-config" name="{{_name}}[custom_class]">
24
+ </div>
25
+ </div>
26
+ <?php
27
+ }
includes/field_processors.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+
6
+ add_filter('caldera_forms_process_field_file', 'cf_handle_file_upload', 10, 3);
7
+
8
+
9
+ function cf_handle_file_upload($entry, $field, $form){
10
+
11
+ if(!empty($_FILES[$field['ID']]['size'])){
12
+ // check is allowed
13
+ if(!empty($field['config']['allowed'])){
14
+ $types = explode(',',$field['config']['allowed']);
15
+
16
+ foreach($types as &$type){
17
+ $type=trim($type);
18
+ }
19
+ $check = pathinfo($_FILES[$field['ID']]['name']);
20
+ if(!in_array( $check['extension'], $types)){
21
+ if(count($types) > 1){
22
+ return array('_fail'=>__('File type not allowed. Allowed types are: ', 'caldera-forms') . ' '. implode(', ', $types) );
23
+ }else{
24
+ return array('_fail'=>__('File type needs to be', 'caldera-forms') . ' .' . $types[0] );
25
+ }
26
+ }
27
+
28
+ }
29
+ if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );
30
+
31
+ $upload = wp_handle_upload($_FILES[$field['ID']], array( 'test_form' => false ), date('Y/m') );
32
+
33
+ if(empty($upload['error'])){
34
+ return $upload['url'];
35
+ }else{
36
+ return new WP_Error( 'fail', $upload['error'] );
37
+ }
38
+ }
39
+ }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: Desertsnowman
3
  Tags: forms, formbuilder, form builder, contact form, contact, custom form, custom forms, forms creator
4
  Requires at least: 3.9
5
  Tested up to: 3.9.1
6
- Stable tag: 1.0.0
7
  License: GPLv2
8
 
9
  Create complex grid based, responsive forms easily with an easy to use drag and drop layout builder.
@@ -11,16 +11,49 @@ Create complex grid based, responsive forms easily with an easy to use drag and
11
  == Description ==
12
  Caldera Forms is a free, simple form builder with a layout builder that enables you to create the format you want for your form. It is fully responsive and with form processors, it gives you flexibility to handle the form data how you need it.
13
 
14
- Add form processors to your forms to have the data go where you need it. Yo can stack up processors to have them do multiple tasks. Currently, there is only an Auto-Responder and Redirect processor, but more are coming.
 
15
 
16
- Advanced conditional logic take away the basic "Match all or one" and gives you conditional groups. This allows you to create simple conditionals or complex, multi-condition matching.
 
 
 
 
 
 
 
 
 
17
 
18
- Everything can be extended. For developers, there are enough hooks and filters to build on. From frontend handling, to form processing, to editor panels, to field types. At it's core, it's a framework for building applications so you can make what you want.
 
19
 
20
- This is only the first version and much more is coming.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  For issues and updates - Caldera Forms is on [GitHub](https://github.com/Desertsnowman/Caldera-Forms)
23
 
 
 
24
  == Installation ==
25
 
26
  Upload the caldera-forms folder to /wp-content/plugins/
@@ -38,7 +71,118 @@ none yet.
38
  3. **Great Looking Forms** - Create great looking forms.
39
 
40
  == Changelog ==
41
- 1.0.0: initial release
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
  == Upgrade Notice ==
44
  still new, so nothing to upgrade.
3
  Tags: forms, formbuilder, form builder, contact form, contact, custom form, custom forms, forms creator
4
  Requires at least: 3.9
5
  Tested up to: 3.9.1
6
+ Stable tag: 1.0.91
7
  License: GPLv2
8
 
9
  Create complex grid based, responsive forms easily with an easy to use drag and drop layout builder.
11
  == Description ==
12
  Caldera Forms is a free, simple form builder with a layout builder that enables you to create the format you want for your form. It is fully responsive and with form processors, it gives you flexibility to handle the form data how you need it.
13
 
14
+ For issues and updates - Caldera Forms is on [GitHub](https://github.com/Desertsnowman/Caldera-Forms)
15
+ Form Demos and Templates can be found on the demo site [Caldera Forms Demos](http://demo.calderaforms.com/)
16
 
17
+ = A Few Feature Highlights =
18
+ * Responsive Grid design based on Bootstrap 3
19
+ * Advanced Conditionals allows for multi, complex matching
20
+ * Form Processors allows for stacking up form functionality, conditionaly
21
+ * Export and Import forms across installations
22
+ * Ajax or Page reload
23
+ * Multipage forms
24
+ * CSV of submission attached to notification email
25
+ * Auto Responder
26
+ * File Uploads
27
 
28
+ = Auto Values & Magic Tags =
29
+ Capture system values, Post/Page data and custom fields, User data, and processor returns.
30
 
31
+ = Current Available Fields (more can be added on request) =
32
+ * Calculation
33
+ * Range Slider
34
+ * Star Rating
35
+ * Phone
36
+ * Text - Includes Custom Masking
37
+ * File Upload
38
+ * reCaptcha
39
+ * HTML content block - with dynamic data binding ( %field_slug% updates dynamically in html )
40
+ * Hidden
41
+ * Button
42
+ * Email
43
+ * Paragraph
44
+ * Toggle Switch
45
+ * Dropdown Select
46
+ * Checkbox
47
+ * Radio
48
+ * Date Picker
49
+ * Color Picker
50
+
51
+ Everything can be extended. For developers, there are enough hooks and filters to build on. From frontend handling, to form processing, to editor panels, to field types. At it's core, it's a framework for building applications so you can make what you want.
52
 
53
  For issues and updates - Caldera Forms is on [GitHub](https://github.com/Desertsnowman/Caldera-Forms)
54
 
55
+
56
+
57
  == Installation ==
58
 
59
  Upload the caldera-forms folder to /wp-content/plugins/
71
  3. **Great Looking Forms** - Create great looking forms.
72
 
73
  == Changelog ==
74
+
75
+ = 1.0.91 (27 July, 2014) =
76
+
77
+ = Bugfix =
78
+ * Fixed the preview button
79
+
80
+ = Added =
81
+ * Form ID added as form class
82
+
83
+
84
+ = 1.0.9 (25 July, 2014) =
85
+
86
+ = Bugfix =
87
+ * Conditionals error on numerical condition value
88
+ * placeholder field took preference on masked input instead of default field
89
+
90
+ = Additions =
91
+ * Form preview button
92
+ * Processors can now return an error to stop process chain
93
+ * Process transient now accessable for storing process data for redirects and such
94
+ * Field ID added to field config panel for reference
95
+ * Extra checks for valid data
96
+ * Extra filters
97
+ * Meta Data view templates to processors
98
+
99
+ = 1.0.8 (21 July, 2014) =
100
+
101
+ = Bugfix =
102
+ * PHP 5.2+ compatibility fix on grid generation
103
+ * Multi-page bug that stopped the page config from being saved
104
+ * Range Slider bug fixed that broke sliders on multipage forms
105
+
106
+ = 1.0.7 (20 July, 2014) =
107
+
108
+ = Bugfix =
109
+ * Left off an important table update for the status- very sorry. I hate doing two updates in a day.
110
+
111
+ = 1.0.6 (20 July, 2014) =
112
+
113
+ = Additions =
114
+ * Range Slider field type
115
+ * Star Rating view filter (show starts in entry view)
116
+ * Auto generate mail body from submissions + {summary} magic tag
117
+ * field %field_slug% tags dynamically bound in HTML field type ( updates dynamically with field values )
118
+ * Gravitar field binding to antry capture to show gravitar of form submitter if email is available - else uses userid of logged in user.
119
+ * Trash, restore & delete for submission entry management.
120
+ * Bulk actions for submission management (trash, delete, restore & export)
121
+ * Form Processor return values are now bindable options for other processors
122
+ * Field tags are now bindable values for processors
123
+
124
+
125
+ = Bug Fixes =
126
+ * max_input_limit for configurations. fixed without the need to update php.ini (w00t!)
127
+ * fixed conditionals support for IE8
128
+ * some minor fixes I can't remember right now.
129
+
130
+ = Enhancements =
131
+ * Added processor meta values so that form processors can add to the form submission
132
+ * optimized js in editor UI
133
+ * more filters and actions for developers
134
+ * other stiff I can't remember
135
+
136
+ = 1.0.5 (13 July, 2014) =
137
+
138
+ = Additions =
139
+ * Multi Page Forms (still some work to do to make it easier)
140
+ * Bulk option insert for select fields (dropdown, radio, checkboxes, toggle button)
141
+ * Magic Tags on fields and mailer
142
+ * tag conditionals on email message
143
+ * Ajax return filter
144
+ * Placeholder field to add a custom placeholder rather than using the lable.
145
+
146
+ = Bug Fixes =
147
+ * Bug in ajax verification
148
+ * Missing checkmark image in chrome
149
+ * Conditionals on checkboxes now works
150
+ * Conditionals performance on frontend
151
+ * Calculations field responds to conditionals correctly
152
+ * Static field types (select options etc) cannot be minipulated from frontend. Preprocessing on submit restores set values.
153
+
154
+ = Enhancements =
155
+ * Switched redirect filter and action order
156
+ * File upload method to use WordPress' handler to prevent issues on some installs.
157
+ * Field dragging reduces to a set block for easier field placement.
158
+
159
+ = 1.0.4 (20 June, 2014) =
160
+
161
+ * Added Ajax submissions option - found in General Settings.
162
+ * Added custom field class - field wrapper based
163
+ * Added general input masking for single line text field
164
+ * Added Form Exporting and Importing
165
+
166
+ = 1.0.3 (12 June, 2014) =
167
+
168
+ * Added custom input mask format for phone number
169
+ * Cleaned up form style
170
+ * Fixed bug in datepicker with no arrows showing
171
+ * Fixed text field showing behind star rating
172
+
173
+ = 1.0.2 (11 June, 2014) =
174
+
175
+ * Added Star Rating field
176
+ * Added Calculations
177
+
178
+ = 1.0.1 (10 June, 2014) =
179
+
180
+ * Added Phone Field Type
181
+ * Additional Hooks & Filters
182
+ * Some Bug fixes
183
+
184
+ = 1.0.0 =
185
+ Initial Release
186
 
187
  == Upgrade Notice ==
188
  still new, so nothing to upgrade.
ui/admin.php CHANGED
@@ -42,8 +42,11 @@ $modal_new_form = __('Create Form', 'caldera-forms').'|{"data-action" : "create_
42
  v<?php echo CFCORE_VER; ?>
43
  </li>
44
  <li class="caldera-forms-toolbar-item">
45
- <a class="button ajax-trigger" data-request="start_new_form" data-modal-buttons='<?php echo $modal_new_form; ?>' data-modal-width="600" data-modal-height="400" data-load-class="none" data-modal="new_form" data-modal-title="Create New Form" data-template="#new-form-tmpl"><?php echo __('New Form', 'caldera-forms'); ?></a>
46
  </li>
 
 
 
47
  <li class="caldera-forms-toolbar-item">
48
  &nbsp;
49
  </li>
@@ -87,7 +90,7 @@ $modal_new_form = __('Create Form', 'caldera-forms').'|{"data-action" : "create_
87
  foreach($forms as $form_id=>$form){
88
 
89
  if(!empty($form['db_support'])){
90
- $total = $wpdb->get_var($wpdb->prepare("SELECT COUNT(`id`) AS `total` FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `form_id` = %s;", $form_id));
91
  }else{
92
  $total = __('Disabled', 'caldera-forms');
93
  }
@@ -121,7 +124,7 @@ $modal_new_form = __('Create Form', 'caldera-forms').'|{"data-action" : "create_
121
  <td>
122
  <?php echo $form['name']; ?>
123
  <div class="row-actions">
124
- <span class="edit"><a class="form-control" href="admin.php?page=caldera-forms&edit=<?php echo $form_id; ?>"><?php echo __('Edit Form', 'caldera-forms'); ?></a> | </span>
125
  <?php if(!empty($form['db_support'])){ ?><span class="edit"><a class="form-control form-entry-trigger ajax-trigger" href="#entres"
126
 
127
  data-action="browse_entries"
@@ -130,17 +133,20 @@ $modal_new_form = __('Create Form', 'caldera-forms').'|{"data-action" : "create_
130
  data-template="#forms-list-alt-tmpl"
131
  data-active-element="#form_row_<?php echo $form_id; ?>"
132
  data-load-class="spinner"
133
- data-active-class="highlight"
134
  data-group="entry_nav"
135
  data-callback="setup_pagination"
 
136
  data-page="1"
137
 
138
  ><?php echo __('View Entries', 'caldera-forms'); ?></a> | </span><?php } ?>
139
- <span class="trash form-delete"><a class="form-control" data-confirm="<?php echo __('This will delete this form permanently. Continue?', 'caldera-forms'); ?>" href="admin.php?page=caldera-forms&delete=<?php echo $form_id; ?>&cal_del=<?php echo wp_create_nonce( 'cf_del_frm' ); ?>"><?php echo __('Delete Form', 'caldera-forms'); ?></a></span>
 
 
140
 
141
  </div>
142
  </td>
143
- <td style="width:4em; text-align:center;"><?php echo $total; ?></td>
144
  </tr>
145
 
146
 
@@ -160,8 +166,43 @@ $modal_new_form = __('Create Form', 'caldera-forms').'|{"data-action" : "create_
160
  </div>
161
  <div class="form-entries-wrap">
162
  <div class="caldera-entry-exporter" style="display:none;">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  <a href="" class="button caldera-forms-entry-exporter"><?php echo __('Export Entries', 'caldera-forms'); ?></a>
 
 
 
 
 
164
  </div>
 
165
  <?php do_action('caldera_forms_entries_toolbar'); ?>
166
  <div class="tablenav caldera-table-nav" style="display:none;">
167
  <div class="tablenav-pages">
@@ -175,7 +216,7 @@ $modal_new_form = __('Create Form', 'caldera-forms').'|{"data-action" : "create_
175
  </span>
176
  </div>
177
  </div>
178
- <div id="form-entries-viewer"></div>
179
  </div>
180
  </div>
181
 
@@ -184,6 +225,19 @@ do_action('caldera_forms_admin_templates');
184
  ?>
185
  <script type="text/javascript">
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  function new_form_redirect(obj){
188
  if(typeof obj.data === 'string'){
189
  window.location = 'admin.php?page=caldera-forms&edit=' + obj.data;
@@ -215,10 +269,15 @@ function serialize_modal_form(el){
215
  function setup_pagination(obj){
216
 
217
  var total = obj.rawData.total,
 
 
 
218
  exporter = jQuery('.caldera-entry-exporter'),
219
  tense = ( total === 1 ? ' <?php echo __('entry', 'caldera-pages'); ?>' : ' <?php echo __('entries', 'caldera-pages'); ?>' ),
220
  pages = obj.rawData.pages,
221
  current = obj.rawData.current_page,
 
 
222
  pagenav = jQuery('.caldera-table-nav'),
223
  page_links = pagenav.find('.pagination-links'),
224
  entries_total = pagenav.find('.displaying-num'),
@@ -227,22 +286,48 @@ function setup_pagination(obj){
227
  first_page = pagenav.find('.first-page'),
228
  prev_page = pagenav.find('.prev-page'),
229
  next_page = pagenav.find('.next-page'),
230
- last_page = pagenav.find('.last-page');
 
 
 
 
231
 
232
  obj.params.trigger.data('page', current);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
 
 
234
  pagenav.data('total', pages);
235
-
236
- if(total < 1){
237
  pagenav.hide();
238
  exporter.hide();
239
  return;
240
- }else if(pages <= 1){
 
 
241
  page_links.hide();
242
  }else{
243
  page_links.show();
244
  }
245
- exporter.find('.caldera-forms-entry-exporter').attr('href', 'admin.php?page=caldera-forms&export=' + obj.params.trigger.data('form'));
246
  exporter.show();
247
  pagenav.show();
248
  page_links.find('a').removeClass('disabled');
42
  v<?php echo CFCORE_VER; ?>
43
  </li>
44
  <li class="caldera-forms-toolbar-item">
45
+ <a class="button ajax-trigger" data-request="start_new_form" data-modal-buttons='<?php echo $modal_new_form; ?>' data-modal-width="600" data-modal-height="400" data-load-class="none" data-modal="new_form" data-modal-title="<?php echo __('Create New Form', 'caldera-forms'); ?>" data-template="#new-form-tmpl"><?php echo __('New Form', 'caldera-forms'); ?></a>
46
  </li>
47
+ <li class="caldera-forms-toolbar-item">
48
+ <a class="button ajax-trigger" data-request="start_new_form" data-modal-width="400" data-modal-height="192" data-load-class="none" data-modal="new_form" data-template="#import-form-tmpl" data-modal-title="<?php echo __('Import Form', 'caldera-forms'); ?>" ><?php echo __('Import', 'caldera-forms'); ?></a>
49
+ </li>
50
  <li class="caldera-forms-toolbar-item">
51
  &nbsp;
52
  </li>
90
  foreach($forms as $form_id=>$form){
91
 
92
  if(!empty($form['db_support'])){
93
+ $total = $wpdb->get_var($wpdb->prepare("SELECT COUNT(`id`) AS `total` FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `form_id` = %s && `status` = 'active';", $form_id));
94
  }else{
95
  $total = __('Disabled', 'caldera-forms');
96
  }
124
  <td>
125
  <?php echo $form['name']; ?>
126
  <div class="row-actions">
127
+ <span class="edit"><a class="form-control" href="admin.php?page=caldera-forms&edit=<?php echo $form_id; ?>"><?php echo __('Edit', 'caldera-forms'); ?></a> | </span>
128
  <?php if(!empty($form['db_support'])){ ?><span class="edit"><a class="form-control form-entry-trigger ajax-trigger" href="#entres"
129
 
130
  data-action="browse_entries"
133
  data-template="#forms-list-alt-tmpl"
134
  data-active-element="#form_row_<?php echo $form_id; ?>"
135
  data-load-class="spinner"
136
+ data-active-class="highlight"
137
  data-group="entry_nav"
138
  data-callback="setup_pagination"
139
+ data-status="active"
140
  data-page="1"
141
 
142
  ><?php echo __('View Entries', 'caldera-forms'); ?></a> | </span><?php } ?>
143
+ <span class="export"><a class="form-control" href="admin.php?page=caldera-forms&export-form=<?php echo $form_id; ?>&cal_del=<?php echo wp_create_nonce( 'cf_del_frm' ); ?>"><?php echo __('Export Form', 'caldera-forms'); ?></a> | </span>
144
+ <span class="trash form-delete"><a class="form-control" data-confirm="<?php echo __('This will delete this form permanently. Continue?', 'caldera-forms'); ?>" href="admin.php?page=caldera-forms&delete=<?php echo $form_id; ?>&cal_del=<?php echo wp_create_nonce( 'cf_del_frm' ); ?>"><?php echo __('Delete', 'caldera-forms'); ?></a></span>
145
+
146
 
147
  </div>
148
  </td>
149
+ <td style="width:4em; text-align:center;" class="entry_count_<?php echo $form_id; ?>"><?php echo $total; ?></td>
150
  </tr>
151
 
152
 
166
  </div>
167
  <div class="form-entries-wrap">
168
  <div class="caldera-entry-exporter" style="display:none;">
169
+
170
+ <span class="toggle_option_preview" style="">
171
+ <button type="button" class="status_toggles button button-primary ajax-trigger" style="margin-top: 1px;"
172
+ data-action="browse_entries"
173
+ data-target="#form-entries-viewer"
174
+ data-form=""
175
+ data-template="#forms-list-alt-tmpl"
176
+ data-load-class="spinner"
177
+ data-active-class="button-primary"
178
+ data-group="status_nav"
179
+ data-callback="setup_pagination"
180
+ data-page="1"
181
+ data-status="active"
182
+ >Active <span class="current-status-count"></span></button>
183
+ <button type="button" class="status_toggles button ajax-trigger" style="margin-top: 1px; margin-right: 10px;"
184
+ data-action="browse_entries"
185
+ data-target="#form-entries-viewer"
186
+ data-form=""
187
+ data-template="#forms-list-alt-tmpl"
188
+ data-load-class="spinner"
189
+ data-active-class="button-primary"
190
+ data-group="status_nav"
191
+ data-callback="setup_pagination"
192
+ data-page="1"
193
+ data-status="trash"
194
+ >Trash <span class="current-status-count"></span></button>
195
+ </span>
196
+
197
+
198
  <a href="" class="button caldera-forms-entry-exporter"><?php echo __('Export Entries', 'caldera-forms'); ?></a>
199
+
200
+ <select id="cf_bulk_action" name="action">
201
+ </select>
202
+ <button type="button" class="button cf-bulk-action"><?php echo __('Apply'); ?></button>
203
+
204
  </div>
205
+
206
  <?php do_action('caldera_forms_entries_toolbar'); ?>
207
  <div class="tablenav caldera-table-nav" style="display:none;">
208
  <div class="tablenav-pages">
216
  </span>
217
  </div>
218
  </div>
219
+ <div id="form-entries-viewer"></div>
220
  </div>
221
  </div>
222
 
225
  ?>
226
  <script type="text/javascript">
227
 
228
+ function cf_refresh_view(obj){
229
+
230
+ jQuery('.entry_count_' + obj.params.trigger.data('form')).html(obj.rawData.total);
231
+ jQuery('.status_toggles[data-status="trash"] .current-status-count').html(obj.rawData.trash);
232
+ jQuery('.status_toggles[data-status="active"] .current-status-count').html(obj.rawData.total);
233
+ if(obj.rawData.undo === obj.params.trigger.data('panel')){
234
+ obj.params.trigger.closest('tr').addClass('cf-deleted-row');
235
+ }else{
236
+ obj.params.trigger.closest('tr').removeClass('cf-deleted-row');
237
+ }
238
+ obj.params.trigger.data('do', obj.rawData.undo).html(obj.rawData.undo_text).removeClass('disabled');
239
+ }
240
+
241
  function new_form_redirect(obj){
242
  if(typeof obj.data === 'string'){
243
  window.location = 'admin.php?page=caldera-forms&edit=' + obj.data;
269
  function setup_pagination(obj){
270
 
271
  var total = obj.rawData.total,
272
+ trash = obj.rawData.trash,
273
+ active = obj.rawData.active,
274
+ toggles = jQuery('.status_toggles'),
275
  exporter = jQuery('.caldera-entry-exporter'),
276
  tense = ( total === 1 ? ' <?php echo __('entry', 'caldera-pages'); ?>' : ' <?php echo __('entries', 'caldera-pages'); ?>' ),
277
  pages = obj.rawData.pages,
278
  current = obj.rawData.current_page,
279
+ form = obj.params.trigger.data('form'),
280
+ status = obj.params.trigger.data('status'),
281
  pagenav = jQuery('.caldera-table-nav'),
282
  page_links = pagenav.find('.pagination-links'),
283
  entries_total = pagenav.find('.displaying-num'),
286
  first_page = pagenav.find('.first-page'),
287
  prev_page = pagenav.find('.prev-page'),
288
  next_page = pagenav.find('.next-page'),
289
+ last_page = pagenav.find('.last-page'),
290
+ form_trigger = jQuery('.form_entry_row.highlight').find('.form-entry-trigger'),
291
+ bulk_actions = jQuery('#cf_bulk_action'),
292
+ bulk_template = jQuery('#bulk-actions-'+status+'-tmpl').html(),
293
+ entry_count = jQuery('.entry_count_' + form);
294
 
295
  obj.params.trigger.data('page', current);
296
+ form_trigger.data('status', status);
297
+ bulk_actions.html(bulk_template);
298
+
299
+ toggles.removeClass('button-primary').removeClass('disabled');
300
+ toggles.filter('[data-status="'+status+'"]').addClass('button-primary');
301
+ toggles.each(function(k,v){
302
+ var el = jQuery(v);
303
+ if(typeof obj.rawData[el.data('status')] === 'number'){
304
+ if(obj.rawData[el.data('status')] > 0){
305
+ el.find('.current-status-count').html(obj.rawData[el.data('status')]);
306
+ }else{
307
+ el.find('.current-status-count').html('');
308
+ }
309
+ }
310
+ });
311
+ // update count
312
+ entry_count.html(active);
313
+ //bulk-actions-active-tmpl
314
 
315
+ // add form id to toggles
316
+ toggles.data('form', form)
317
  pagenav.data('total', pages);
318
+ /*
319
+ if(total < 1 && trash < 1){
320
  pagenav.hide();
321
  exporter.hide();
322
  return;
323
+ }else if(total < 1 && trash < 1){
324
+ */
325
+ if(pages <= 1){
326
  page_links.hide();
327
  }else{
328
  page_links.show();
329
  }
330
+ exporter.find('.caldera-forms-entry-exporter').attr('href', 'admin.php?page=caldera-forms&export=' + form);
331
  exporter.show();
332
  pagenav.show();
333
  page_links.find('a').removeClass('disabled');
ui/admin_templates.php CHANGED
@@ -1,5 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <script type="text/html" id="new-form-tmpl">
2
- <form class="new-form-form">
3
  <?php
4
  do_action('caldera_forms_new_form_template_start');
5
  ?>
@@ -23,29 +51,35 @@
23
  <script type="text/html" id="forms-list-alt-tmpl">
24
 
25
  {{#if entries}}
26
- <div class="list form-panel postbox">
27
- <table class="table table-condensed">
28
  <thead>
29
  <tr>
 
30
  <th><?php echo __('ID', 'caldera-forms'); ?></th>
31
  <th><?php echo __('Submitted', 'caldera-forms'); ?></th>
32
  {{#each fields}}
33
  <th>{{this}}</th>
34
  {{/each}}
35
- <th></th>
36
  </tr>
37
  </thead>
38
  <tbody>
 
39
  {{#each entries}}
40
- <tr>
 
41
  <td>{{_entry_id}}</td>
42
  <td>{{_date}}</td>
43
  {{#each data}}
44
  <td>{{{this}}}</td>
45
  {{/each}}
46
- <td style="text-align: right;"><?php do_action('caldera_forms_entry_actions'); ?></td>
47
  </tr>
48
  {{/each}}
 
 
 
49
  </tbody>
50
  </table>
51
  </div>
@@ -54,9 +88,28 @@
54
  {{/if}}
55
  </script>
56
  <script type="text/html" id="view-entry-tmpl">
57
- <div class="form-panel">
58
- <table class="table table-condensed">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  <thead>
 
60
  <tr>
61
  <th><?php echo __('Field', 'caldera-forms'); ?></th>
62
  <th><?php echo __('Value', 'caldera-forms'); ?></th>
@@ -70,6 +123,141 @@
70
  </tr>
71
  {{/each}}
72
  </tbody>
73
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  </div>
75
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="bulk-actions-active-tmpl">
2
+ <option selected="selected" value=""><?php echo __('Bulk Actions'); ?></option>
3
+ <option value="export"><?php echo __('Export Selected', 'caldera-forms'); ?></option>
4
+ <option value="trash"><?php echo __('Move to Trash'); ?></option>
5
+ </script>
6
+ <script type="text/html" id="bulk-actions-trash-tmpl">
7
+ <option selected="selected" value=""><?php echo __('Bulk Actions'); ?></option>
8
+ <option value="export"><?php echo __('Export Selected', 'caldera-forms'); ?></option>
9
+ <option value="active"><?php echo __('Restore'); ?></option>
10
+ <option value="delete"><?php echo __('Delete Permanently'); ?></option>
11
+ </script>
12
+ <script type="text/html" id="import-form-tmpl">
13
+ <form class="new-form-form" action="admin.php?page=caldera-forms&import=true" enctype="multipart/form-data" method="POST">
14
+ <?php
15
+ wp_nonce_field( 'cf-import', 'cfimporter' );
16
+ do_action('caldera_forms_import_form_template_start');
17
+ ?>
18
+ <p class="description"><?php echo __('Import a Caldera Form from a .json export file.', 'caldera-forms'); ?></p>
19
+ <input type="file" class="new-form-name" name="import_file" required="required">
20
+ <p class="import-warning" style="color:#ff0000;"><?php echo __('This will overwrite a form if it already exists.', 'caldera-forms'); ?></p>
21
+
22
+ <hr>
23
+ <button type="submit" class="button button-primary" style="float:right;"><?php echo __('Import Form', 'caldera-forms'); ?></button>
24
+ <?php
25
+ do_action('caldera_forms_import_form_template_end');
26
+ ?>
27
+ </form>
28
+ </script>
29
  <script type="text/html" id="new-form-tmpl">
30
+ <form class="new-form-form ajax-trigger" data-action="create_form" data-active-class="disabled" data-load-class="disabled" data-callback="new_form_redirect" data-before="serialize_modal_form" data-modal-autoclose="new_form">
31
  <?php
32
  do_action('caldera_forms_new_form_template_start');
33
  ?>
51
  <script type="text/html" id="forms-list-alt-tmpl">
52
 
53
  {{#if entries}}
54
+ <div class="list form-panel postbox" data-form="{{form}}">
55
+ <table class="table table-condensed cf-table-viewer">
56
  <thead>
57
  <tr>
58
+ <th style="width:16px;"><input type="checkbox" class="cf-bulkcheck"></th>
59
  <th><?php echo __('ID', 'caldera-forms'); ?></th>
60
  <th><?php echo __('Submitted', 'caldera-forms'); ?></th>
61
  {{#each fields}}
62
  <th>{{this}}</th>
63
  {{/each}}
64
+ <th style="width: 100px;"></th>
65
  </tr>
66
  </thead>
67
  <tbody>
68
+ {{#if entries}}
69
  {{#each entries}}
70
+ <tr id="entry_row_{{_entry_id}}">
71
+ <td style="width:16px;"><input type="checkbox" class="cf-entrycheck" value="{{_entry_id}}"></td>
72
  <td>{{_entry_id}}</td>
73
  <td>{{_date}}</td>
74
  {{#each data}}
75
  <td>{{{this}}}</td>
76
  {{/each}}
77
+ <td style="text-align: right; width: 100px;"><?php do_action('caldera_forms_entry_actions'); ?></td>
78
  </tr>
79
  {{/each}}
80
+ {{else}}
81
+ <tr><td colspan="100"><?php echo __('No entries found', 'caldera-forms'); ?></td></tr>
82
+ {{/if}}
83
  </tbody>
84
  </table>
85
  </div>
88
  {{/if}}
89
  </script>
90
  <script type="text/html" id="view-entry-tmpl">
91
+ {{#if user}}
92
+ <div class="modal-side-bar has-avatar">
93
+ <span class="user-avatar user-avatar-{{user/ID}}"{{#if user/name}} title="{{user/name}}"{{/if}}>
94
+ {{{user/avatar}}}
95
+ </span>
96
+ {{#if meta}}
97
+ <ul class="modal-side-tabs">
98
+ <li><a href="#main-entry-panel" class="modal-side-tab active"><?php echo __('Entry'); ?></a></li>
99
+ {{#each meta}}
100
+ <li><a href="#meta-{{@key}}" class="modal-side-tab">{{name}}</a></li>
101
+ {{/each}}
102
+ </ul>
103
+ {{/if}}
104
+ </div>
105
+ {{/if}}
106
+ <div class="form-panel{{#if user}} modal-inside{{/if}}">
107
+ <div id="main-entry-panel" class="tab-detail-panel">
108
+ <h4><?php echo __('Submitted', 'caldera-forms'); ?> <small class="description">{{date}}</small></h4>
109
+ <hr>
110
+ <table class="table table-condensed">
111
  <thead>
112
+
113
  <tr>
114
  <th><?php echo __('Field', 'caldera-forms'); ?></th>
115
  <th><?php echo __('Value', 'caldera-forms'); ?></th>
123
  </tr>
124
  {{/each}}
125
  </tbody>
126
+ </table></div>
127
+
128
+ {{#if meta}}
129
+ {{#each meta}}
130
+ <div id="meta-{{@key}}" class="tab-detail-panel" style="display:none;">
131
+ <h4>{{name}}</h4>
132
+ <hr>
133
+ {{#unless template}}
134
+ <table class="table table-condensed">
135
+ {{#each data}}
136
+ <thead>
137
+ {{#if title}}
138
+ <tr>
139
+ <th colspan="2" class="active">{{title}}</th>
140
+ </tr>
141
+ {{/if}}
142
+ <tr>
143
+ <th><?php echo __('Field', 'caldera-forms'); ?></th>
144
+ <th><?php echo __('Value', 'caldera-forms'); ?></th>
145
+ </tr>
146
+ </thead>
147
+ <tbody>
148
+ {{#each entry}}
149
+ <tr>
150
+ <th>{{meta_key}}</th>
151
+ <td>{{{meta_value}}}</td>
152
+ </tr>
153
+ {{/each}}
154
+ </tbody>
155
+ {{/each}}
156
+ </table>
157
+ {{/unless}}
158
+ <?php do_action('caldera_forms_entry_meta_templates'); ?>
159
+ </div>
160
+ {{/each}}
161
+ {{/if}}
162
  </div>
163
+ </script>
164
+ <script type="text/javascript">
165
+
166
+ jQuery(function($){
167
+
168
+ $('body').on('change', '.cf-bulkcheck', function(){
169
+
170
+ var checked = $(this),
171
+ parent = checked.closest('.cf-table-viewer'),
172
+ checks = parent.find('.cf-entrycheck'),
173
+ action = $('#cf_bulk_action');
174
+
175
+ checks.prop('checked', checked.prop('checked'));
176
+
177
+ });
178
+
179
+ $('body').on('change', '.cf-entrycheck', function(){
180
+
181
+ var checkall = $('.cf-bulkcheck'),
182
+ allchecks = $('.cf-entrycheck'),
183
+ checked = $('.cf-entrycheck:checked');
184
+
185
+ if(allchecks.length != checked.length){
186
+ checkall.prop('checked', false);
187
+ }else{
188
+ checkall.prop('checked', true);
189
+ }
190
+
191
+ });
192
+ $('body').on('click', '.cf-bulk-action', function(){
193
+
194
+ var action = $('#cf_bulk_action'),
195
+ bulkCheck = $('.cf-bulkcheck');
196
+
197
+ if( !action.val().length){
198
+ return;
199
+ }
200
+
201
+ action.prop('disabled', true);
202
+ var checks = $('#form-entries-viewer .cf-entrycheck:checked'),
203
+ form = $('#form-entries-viewer .list.form-panel').data('form');
204
+
205
+ if(checks.length){
206
+
207
+ var list = [],
208
+ rows = [];
209
+ for( var i = 0; i<checks.length; i++){
210
+ list.push(checks[i].value);
211
+ rows.push('#entry_row_' + checks[i].value);
212
+ }
213
+ var row_items = $(rows.join(','));
214
+
215
+ var data = {
216
+ 'action' : 'cf_bulk_action',
217
+ 'do' : action.val(),
218
+ 'items' : list,
219
+ 'form' : form
220
+ }
221
+
222
+ row_items.animate({"opacity": .4}, 500);
223
+ $.post(ajaxurl, data, function(res){
224
+ if(res.status && res.entries && res.total){
225
+ row_items.remove();
226
+ $('.entry_count_' + form).html(res.total);
227
+ $('input.current-page').trigger('change');
228
+ }else if(res.url){
229
+ row_items.animate({"opacity": 1}, 500);
230
+ window.location = res.url;
231
+ }else if(res.status === 'reload'){
232
+ $('input.current-page').trigger('change');
233
+ }
234
+ action.val('').prop('disabled', false);
235
+ bulkCheck.prop('checked', false);
236
+ });
237
+ }else{
238
+ action.prop('disabled', false);
239
+ }
240
+
241
+ });
242
+
243
+ });
244
+
245
+ </script>
246
+
247
+
248
+
249
+
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
ui/edit-entry.php ADDED
@@ -0,0 +1,404 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ global $field_type_list, $field_type_templates, $wpdb;
4
+
5
+ // GET ENTRY DETAILS
6
+ $entry = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM `" . $wpdb->prefix . "cf_form_entries` WHERE `id` = %d;", $_GET['edit-entry']));
7
+
8
+ $element = get_option( $entry->form_id );
9
+ if(empty($element)){
10
+ wp_die( __('Invalid Entry', 'caldera-forms') );
11
+ }
12
+ // Navigation
13
+ ?>
14
+ <div class="caldera-editor-header">
15
+ <ul class="caldera-editor-header-nav">
16
+ <li class="caldera-editor-logo">
17
+ <?php echo __('Caldera Forms', 'caldera-forms'); ?>
18
+ </li>
19
+ <li class="caldera-element-type-label">
20
+ <?php echo $element['name']; ?>
21
+ </li>
22
+ <li class="caldera-element-type-label">
23
+ <?php echo __('Entry', 'caldera-forms') .' : '. $entry->id; ?>
24
+ </li>
25
+
26
+ </ul>
27
+ <button class="button button-primary caldera-header-save-button" type="submit"><?php echo __('Update Form', 'caldera-forms'); ?><span id="save_indicator" class="spinner" style="position: absolute; right: -30px;"></span></button>
28
+ </div>
29
+
30
+ <div class="caldera-editor-header caldera-editor-subnav">
31
+ <ul class="caldera-editor-header-nav">
32
+ <li class="sub-meta-line"><?php echo __('Submitted', 'caldera-forms'); ?>: <?php echo date_i18n( get_option('date_format') . ' @ ' . get_option( 'time_format', $entry->datestamp) ); ?></li>
33
+ </ul>
34
+ </div>
35
+ <?php
36
+
37
+
38
+
39
+ // PANEL WRAPPERS & RENDER
40
+ $repeatable_templates = array();
41
+ foreach($panel_extensions as $panel){
42
+ if(empty($panel['tabs'])){
43
+ continue;
44
+ }
45
+
46
+ foreach($panel['tabs'] as $panel_slug=>$tab_setup){
47
+ $active = " style=\"display:none;\"";
48
+ if(!empty($tab_setup['active'])){
49
+ $active = null;
50
+ }
51
+ echo "<div id=\"" . $panel_slug . "-config-panel\" class=\"caldera-editor-body caldera-config-editor-panel " . ( !empty($tab_setup['side_panel']) ? "caldera-config-has-side" : "" ) . "\"".$active.">\r\n";
52
+ if( !empty($tab_setup['side_panel']) ){
53
+ echo "<div id=\"" . $panel_slug . "-config-panel-main\" class=\"caldera-config-editor-main-panel\">\r\n";
54
+ }
55
+ echo '<h3>'.$tab_setup['label'];
56
+ if( !empty( $tab_setup['repeat'] ) ){
57
+ // add a repeater button
58
+ echo " <a href=\"#" . $panel_slug . "_tag\" class=\"add-new-h2 caldera-add-group\" data-group=\"" . $panel_slug . "\">" . __('Add New', 'pods-caldera') . "</a>\r\n";
59
+ }
60
+ // ADD ACTIONS
61
+ if(!empty($tab_setup['actions'])){
62
+ foreach($tab_setup['actions'] as $action){
63
+ include $action;
64
+ }
65
+ }
66
+ echo '</h3>';
67
+ // BUILD CONFIG FIELDS
68
+ if(!empty($tab_setup['fields'])){
69
+ // group index for loops
70
+ $depth = 1;
71
+ if(isset($element['settings'][$panel_slug])){
72
+ // find max depth
73
+ foreach($element['settings'][$panel_slug] as &$field_vars){
74
+ if(count($field_vars) > $depth){
75
+ $depth = count($field_vars);
76
+ }
77
+ }
78
+ }
79
+ for($group_index = 0; $group_index < $depth; $group_index++){
80
+
81
+ if( !empty( $tab_setup['repeat'] ) ){
82
+ echo "<div class=\"caldera-config-editor-panel-group\">\r\n";
83
+ }
84
+ foreach($tab_setup['fields'] as $field_slug=>&$field){
85
+
86
+ $field_name = 'config[settings][' . $panel_slug . '][' . $field_slug . ']';
87
+ $field_id = $panel_slug. '_' . $field_slug . '_' . $group_index;
88
+ $field_label = "<label for=\"" . $field_id . "\">" . $field['label'] . "</label>\r\n";
89
+ $field_placeholder = "";
90
+ $field_required = "";
91
+ if(!empty($field['hide_label'])){
92
+ $field_label = "";
93
+ $field_placeholder = 'placeholder="' . htmlentities( $field['label'] ) .'"';
94
+ }
95
+
96
+
97
+ $field_caption = null;
98
+ if(!empty($field['caption'])){
99
+ $field_caption = "<p class=\"description\">" . $field['caption'] . "</p>\r\n";
100
+ }
101
+
102
+ // blank default
103
+ $field_value = null;
104
+
105
+ if(isset($field['config']['default'])){
106
+ $field_value = $field['config']['default'];
107
+ }
108
+ if(isset($element['settings'][$panel_slug][$field_slug])){
109
+ $field_value = $element['settings'][$panel_slug][$field_slug];
110
+ }
111
+
112
+ $field_wrapper_class = "caldera-config-group";
113
+ $field_input_class = "caldera-config-field";
114
+ $field_class = "field-config";
115
+ if(!empty($field['required'])){
116
+ $field_class .= " required";
117
+ }
118
+ include $field_types[$field['type']]['file'];
119
+
120
+ }
121
+ if( !empty( $tab_setup['repeat'] ) ){
122
+ echo "<a href=\"#remove_" . $panel_slug . "\" class=\"caldera-config-group-remove\">" . __('Remove', 'pods-caldera') . "</a>\r\n";
123
+ echo "</div>\r\n";
124
+ }
125
+ }
126
+
127
+
128
+ /// CHECK GROUP IS REPEATABLE ADN ADD A TEMPLATE IF IT IS
129
+ if( !empty( $tab_setup['repeat'] ) ){
130
+
131
+ $field_template = "<script type=\"text/html\" id=\"" . $panel_slug . "_panel_tmpl\">\r\n";
132
+ $field_template .= " <div class=\"caldera-config-editor-panel-group\">\r\n";
133
+
134
+ foreach($tab_setup['fields'] as $field_slug=>&$field){
135
+
136
+ $field_name = 'config[settings][' . $panel_slug . '][' . $field_slug . '][]';
137
+ $field_id = $panel_slug. '_' . $field_slug;
138
+
139
+ // blank default
140
+ $field_value = null;
141
+
142
+ if(isset($field['config']['default'])){
143
+ $field_value = $field['config']['default'];
144
+ }
145
+
146
+ $field_template .= " <div class=\"caldera-config-group\">\r\n";
147
+ $field_template .= " <label for=\"" . $field_id . "\">" . $field['label'] . "</label>\r\n";
148
+ $field_template .= " <div class=\"caldera-config-field\">\r\n";
149
+ ob_start();
150
+ include $field_types[$field['type']]['file'];
151
+ $field_template .= ob_get_clean();
152
+ $field_template .= " </div>\r\n";
153
+ $field_template .= " </div>\r\n";
154
+
155
+ }
156
+ $field_template .= " <a href=\"#remove-group\" class=\"caldera-config-group-remove\">" . __('Remove', 'pods-caldera') . "</a>\r\n";
157
+ $field_template .= " </div>\r\n";
158
+ $field_template .= "</script>\r\n";
159
+
160
+ $repeatable_templates[] = $field_template;
161
+
162
+ }
163
+
164
+
165
+ }elseif(!empty($tab_setup['canvas'])){
166
+ include $tab_setup['canvas'];
167
+ }
168
+
169
+ if(!empty($tab_setup['side_panel'])){
170
+ echo "</div>\r\n";
171
+ echo "<div id=\"" . $panel_slug . "-config-panel-side\" class=\"caldera-config-editor-side-panel\">\r\n";
172
+
173
+ include $tab_setup['side_panel'];
174
+
175
+ echo "</div>\r\n";
176
+ }
177
+
178
+ echo "</div>\r\n";
179
+ }
180
+ echo "<a name=\"" . $panel_slug . "_tag\"></a>";
181
+ }
182
+
183
+ // PROCESSORS
184
+ do_action('caldera_forms_edit_end', $element);
185
+ ?>
186
+ <script type="text/html" id="field-options-cofnig-tmpl">
187
+ <?php
188
+ echo $field_options_template;
189
+ ?>
190
+ </script>
191
+
192
+ <script type="text/html" id="form-fields-selector-tmpl">
193
+ <div class="modal-tab-panel">
194
+ <?php
195
+
196
+
197
+ $sorted_field_types = array();
198
+ ksort($field_types);
199
+ foreach($field_types as $field_slug=>$config){
200
+ $cats[] = 'General';
201
+ if(!empty($config['category'])){
202
+ $cats = explode(',', $config['category']);
203
+ }
204
+
205
+ $icon = CFCORE_URL . "/assets/images/field.png";
206
+ if(!empty($config['icon'])){
207
+ $icon = $config['icon'];
208
+ }
209
+ foreach($cats as $cat){
210
+ $cat = trim($cat);
211
+ $template = '<div class="form-modal-add-line">';
212
+ $template .= '<button type="button" class="button info-button set-current-field" data-field="{{id}}" data-type="' . $field_slug . '">' . __('Set Element', 'caldera-forms') . '</button>';
213
+ $template .= '<img src="'. $icon .'" class="form-modal-lgo" width="45" height="45">';
214
+ $template .= '<strong>' . $config['field'] . '</strong>';
215
+ $template .= '<p class="description">' . (!empty($config['description']) ? $config['description'] : __('No description given', 'caldera-forms') ) . '</p>';
216
+ $template .= '</div>';
217
+ if(!isset($sorted_field_types[$cat])){
218
+ $sorted_field_types[$cat] = null;
219
+ }
220
+ $sorted_field_types[$cat] .= $template;
221
+ }
222
+ }
223
+ ksort($sorted_field_types);
224
+ echo '<div class="modal-side-bar">';
225
+ echo '<ul class="modal-side-tabs">';
226
+ foreach($sorted_field_types as $cat=>$template){
227
+
228
+ if(!isset($cat_class)){
229
+ $cat_class = ' active';
230
+ }
231
+ echo "<li><a href=\"#modal-category-". sanitize_key( $cat ) ."\" class=\"modal-side-tab". $cat_class ."\">" . $cat . "</a></li>\r\n";
232
+ $cat_class = '';
233
+ }
234
+ echo "</ul>\r\n";
235
+ echo "</div>\r\n";
236
+ $cat_show = false;
237
+ foreach($sorted_field_types as $cat=>$template){
238
+ if(!empty($cat_show)){
239
+ $cat_show = 'style="display: none;"';
240
+ }
241
+ echo '<div id="modal-category-'. sanitize_key( $cat ) .'" class="tab-detail-panel" '.$cat_show.'>';
242
+ echo $template;
243
+ echo '</div>';
244
+ $cat_show = true;
245
+ }
246
+
247
+ ?>
248
+ </div>
249
+ </script>
250
+ <script type="text/html" id="caldera_field_config_wrapper_templ">
251
+ <?php
252
+ echo field_wrapper_template();
253
+ ?>
254
+ </script>
255
+ <script type="text/html" id="field-option-row-tmpl">
256
+ {{#each option}}
257
+ <div class="toggle_option_row">
258
+ <i class="dashicons dashicons-sort" style="padding: 4px 9px;"></i>
259
+ <input type="radio" class="toggle_set_default field-config" name="{{../_name}}[default]" value="{{@key}}" {{#is ../default value="@key"}}checked="checked"{{/is}}>
260
+ <input type="text" class="toggle_value_field field-config" name="{{../_name}}[option][{{@key}}][value]" value="{{value}}" placeholder="value">
261
+ <input type="text" class="toggle_label_field field-config" name="{{../_name}}[option][{{@key}}][label]" value="{{label}}" placeholder="label">
262
+ <button class="button button-small toggle-remove-option" type="button"><i class="icn-delete"></i></button>
263
+ </div>
264
+ {{/each}}
265
+ </script>
266
+ <script type="text/html" id="noconfig_field_templ">
267
+ <div class="caldera-config-group">
268
+ <label>Default</label>
269
+ <div class="caldera-config-field">
270
+ <input type="text" class="block-input field-config" name="{{_name}}[default]" value="{{default}}">
271
+ </div>
272
+ </div>
273
+ </script>
274
+ <script type="text/html" id="conditional-group-tmpl">
275
+ {{#each group}}
276
+ <div class="caldera-condition-group">
277
+ <div class="caldera-condition-group-label"><?php echo __('or', 'caldera-forms'); ?></div>
278
+ <div class="caldera-condition-lines" id="{{id}}_conditions_lines">
279
+ {{#each lines}}
280
+ <div class="caldera-condition-line">
281
+ if
282
+ <select name="config[{{../type}}][{{../../id}}][conditions][group][{{../id}}][{{id}}][field]" data-condition="{{../type}}" class="caldera-field-bind caldera-conditional-field-set" data-id="{{../../id}}" data-default="{{field}}" data-line="{{id}}" data-row="{{../id}}" data-all="true" style="max-width:120px;"></select>
283
+ <select name="config[{{../type}}][{{../../id}}][conditions][group][{{../id}}][{{id}}][compare]" style="max-width:110px;">
284
+ <option value="is" {{#is compare value="is"}}selected="selected"{{/is}}><?php echo __('is', 'caldera-forms'); ?></option>
285
+ <option value="isnot" {{#is compare value="isnot"}}selected="selected"{{/is}}><?php echo __('is not', 'caldera-forms'); ?></option>
286
+ <option value=">" {{#is compare value=">"}}selected="selected"{{/is}}><?php echo __('is greater than', 'caldera-forms'); ?></option>
287
+ <option value="<" {{#is compare value="<"}}selected="selected"{{/is}}><?php echo __('is less than', 'caldera-forms'); ?></option>
288
+ <option value="startswith" {{#is compare value="startswith"}}selected="selected"{{/is}}><?php echo __('starts with', 'caldera-forms'); ?></option>
289
+ <option value="endswith" {{#is compare value="endswith"}}selected="selected"{{/is}}><?php echo __('ends with', 'caldera-forms'); ?></option>
290
+ <option value="contains" {{#is compare value="contains"}}selected="selected"{{/is}}><?php echo __('contains', 'caldera-forms'); ?></option>
291
+ </select>
292
+ <span class="caldera-conditional-field-value" data-value="{{value}}" id="{{id}}_value"><input disabled type="text" value="" placeholder="<?php echo __('Select field first', 'caldera-forms'); ?>" style="max-width: 165px;"></span>
293
+ <button type="button" class="button remove-conditional-line pull-right"><i class="icon-join"></i></button>
294
+ </div>
295
+ {{/each}}
296
+ </div>
297
+ <button type="button" class="button button-small ajax-trigger" data-id="{{../id}}" data-type="{{type}}" data-group="{{id}}" data-request="new_conditional_line" data-target="#{{id}}_conditions_lines" data-callback="rebuild_field_binding" data-template="#conditional-line-tmpl" data-target-insert="append"><?php echo __('Add Condition', 'caldera-forms'); ?></button>
298
+ </div>
299
+ {{/each}}
300
+ </script>
301
+ <script type="text/html" id="conditional-line-tmpl">
302
+ <div class="caldera-condition-line">
303
+ <div class="caldera-condition-line-label"><?php echo __('and', 'caldera-forms'); ?></div>
304
+ if
305
+ <select name="{{name}}[field]" class="caldera-field-bind caldera-conditional-field-set" data-condition="{{type}}" data-id="{{id}}" data-line="{{lineid}}" data-row="{{rowid}}" data-all="true" style="max-width:120px;"></select>
306
+ <select name="{{name}}[compare]" style="max-width:110px;">
307
+ <option value="is"><?php echo __('is', 'caldera-forms'); ?></option>
308
+ <option value="isnot"><?php echo __('is not', 'caldera-forms'); ?></option>
309
+ <option value=">"><?php echo __('is greater than', 'caldera-forms'); ?></option>
310
+ <option value="<"><?php echo __('is less than', 'caldera-forms'); ?></option>
311
+ <option value="startswith"><?php echo __('starts with', 'caldera-forms'); ?></option>
312
+ <option value="endswith"><?php echo __('ends with', 'caldera-forms'); ?></option>
313
+ <option value="contains"><?php echo __('contains', 'caldera-forms'); ?></option>
314
+ </select>
315
+ <span class="caldera-conditional-field-value" id="{{lineid}}_value"><input disabled type="text" value="" placeholder="<?php echo __('Select field first', 'caldera-forms'); ?>" style="max-width: 165px;"></span>
316
+ <button type="button" class="button remove-conditional-line pull-right"><i class="icon-join"></i></button>
317
+ </div>
318
+ </script>
319
+ <?php
320
+
321
+ /// Output the field templates
322
+ foreach($field_type_templates as $key=>$template){
323
+ echo "<script type=\"text/html\" id=\"" . $key . "\">\r\n";
324
+ echo $template;
325
+ echo "\r\n</script>\r\n";
326
+ }
327
+ ?>
328
+ <script type="text/javascript">
329
+
330
+ <?php
331
+ // output fieldtype defaults
332
+ echo implode("\r\n", $field_type_defaults);
333
+
334
+ ?>
335
+ </script>
336
+
337
+
338
+
339
+
340
+
341
+
342
+
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+
356
+
357
+
358
+
359
+
360
+
361
+
362
+
363
+
364
+
365
+
366
+
367
+
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+
390
+
391
+
392
+
393
+
394
+
395
+
396
+
397
+
398
+
399
+
400
+
401
+
402
+
403
+
404
+
ui/edit.php CHANGED
@@ -5,6 +5,10 @@ global $field_type_list, $field_type_templates;
5
  // Load element
6
  $element = get_option( $_GET['edit'] );
7
 
 
 
 
 
8
  if(empty($element['success'])){
9
  $element['success'] = __('Form has successfuly been submitted. Thank you.', 'caldera-forms');
10
  }
@@ -17,8 +21,8 @@ if(!isset($element['db_support'])){
17
  wp_nonce_field( 'cf_edit_element', 'cf_edit_nonce' );
18
 
19
  // Init check
20
- echo "<input name=\"config[_last_updated]\" value=\"" . date('r') . "\" type=\"hidden\">";
21
- echo "<input name=\"config[ID]\" value=\"" . $_GET['edit'] . "\" type=\"hidden\">";
22
 
23
  do_action('caldera_forms_edit_start', $element);
24
 
@@ -41,18 +45,29 @@ $field_type_defaults = array(
41
  $field_options_template = "
42
  <div class=\"caldera-config-group-toggle-options\">
43
  <div class=\"caldera-config-group caldera-config-group-full\">
44
- <button class=\"button block-button add-toggle-option\" type=\"button\">" . __('Add Option', 'caldera-forms') . "</button>
 
 
 
 
 
 
45
  </div>
46
  <div class=\"caldera-config-group caldera-config-group-full\">
47
  <label style=\"padding: 10px;\"><input type=\"radio\" class=\"toggle_set_default field-config\" name=\"{{_name}}[default]\" value=\"\" {{#unless default}}checked=\"checked\"{{/unless}}> " . __('No Default', 'caldera-forms') . "</label>
 
 
 
 
 
48
  </div>
49
  <div class=\"caldera-config-group caldera-config-group-full toggle-options\">
50
  {{#each option}}
51
  <div class=\"toggle_option_row\">
52
  <i class=\"dashicons dashicons-sort\" style=\"padding: 4px 9px;\"></i>
53
  <input type=\"radio\" class=\"toggle_set_default field-config\" name=\"{{../_name}}[default]\" value=\"{{@key}}\" {{#is ../default value=\"@key\"}}checked=\"checked\"{{/is}}>
54
- <input type=\"text\" class=\"toggle_value_field field-config\" name=\"{{../_name}}[option][{{@key}}][value]\" value=\"{{value}}\" placeholder=\"value\">
55
- <input type=\"text\" class=\"toggle_label_field field-config\" name=\"{{../_name}}[option][{{@key}}][label]\" value=\"{{label}}\" placeholder=\"label\">
56
  <button class=\"button button-small toggle-remove-option\" type=\"button\"><i class=\"icn-delete\"></i></button>
57
  </div>
58
  {{/each}}
@@ -60,11 +75,22 @@ $field_options_template = "
60
  </div>
61
  ";
62
 
 
 
 
 
 
 
 
 
 
63
  // Build Field Types List
64
  foreach($field_types as $field_slug=>$config){
65
 
66
  if(!file_exists($config['file'])){
67
- continue;
 
 
68
  }
69
  // type list
70
  $categories[] = __('Basic', 'caldera-forms');
@@ -104,31 +130,37 @@ foreach($field_types as $field_slug=>$config){
104
 
105
  if(empty($config['setup']['preview']) || !file_exists( $config['setup']['preview'] )){
106
 
107
- // simulate a preview with actual field file
108
- $field = array(
109
- 'label' => '{{label}}',
110
- 'slug' => '{{slug}}',
111
- 'type' => '{{type}}',
112
- 'caption' => '{{caption}}',
113
- 'config' => (!empty($config['setup']['default']) ? $config['setup']['default'] : array() )
114
- );
115
-
116
- $field_name = $field['slug'];
117
- $field_id = 'preview_fld_' . $field['slug'];
118
- $field_label = "<label for=\"" . $field_id . "\" class=\"control-label\">" . $field['label'] . "</label>\r\n";
119
- $field_required = "";
120
- $field_placeholder = 'placeholder="' . $field['label'] .'"';
121
- $field_caption = "<span class=\"help-block\">" . $field['caption'] . "</span>\r\n";
122
-
123
- // blank default
124
- $field_value = null;
125
- $field_wrapper_class = "preview-caldera-config-group";
126
- $field_input_class = "preview-caldera-config-field";
127
- $field_class = "preview-field-config";
128
-
129
- ob_start();
130
- include $config['file'];
131
- $field_type_templates['preview-' . sanitize_key( $field_slug ) . "_tmpl"] = ob_get_clean();
 
 
 
 
 
 
132
  }else{
133
  ob_start();
134
  include $config['setup']['preview'];
@@ -196,7 +228,8 @@ function field_wrapper_template($id = '{{id}}', $label = '{{label}}', $slug = '{
196
  <a href="#<?php echo $id; ?>_conditions_pane" class="button ">Conditions</a>
197
  </div>
198
 
199
- <h3 class="caldera-editor-field-title"><?php echo $label; ?>&nbsp;</h3>
 
200
  <div id="<?php echo $id; ?>_settings_pane" class="wrapper-instance-pane">
201
  <div class="caldera-config-group">
202
  <label for="<?php echo $id; ?>_type"><?php echo __('Element Type', 'caldera-forms'); ?></label>
@@ -207,7 +240,14 @@ function field_wrapper_template($id = '{{id}}', $label = '{{label}}', $slug = '{
207
  ?>
208
  </select>
209
  </div>
210
- </div>
 
 
 
 
 
 
 
211
  <div class="caldera-config-group">
212
  <label for="<?php echo $id; ?>_lable"><?php echo __('Name', 'caldera-forms'); ?></label>
213
  <div class="caldera-config-field">
@@ -249,7 +289,6 @@ function field_wrapper_template($id = '{{id}}', $label = '{{label}}', $slug = '{
249
  <input type="checkbox" class="field-config field-checkbox" id="<?php echo $id; ?>_entry_list" name="config[fields][<?php echo $id; ?>][entry_list]" value="1" <?php if($entry_list === 1){ echo 'checked="checked"'; }; ?>>
250
  </div>
251
  </div>
252
-
253
  <div class="caldera-config-field-setup">
254
  </div>
255
  <input type="hidden" class="field_config_string block-input" value="<?php echo htmlentities( $config_str ); ?>">
@@ -269,7 +308,7 @@ function field_wrapper_template($id = '{{id}}', $label = '{{label}}', $slug = '{
269
  <?php do_action('caldera_forms_field_conditionals_template', $id); ?>
270
  <input type="hidden" class="field_conditions_config_string block-input ajax-trigger" data-event="none" data-autoload="true" data-request="build_conditions_config" data-template="#conditional-group-tmpl" data-id="<?php echo $id; ?>" data-target="#<?php echo $id; ?>_conditional_wrap" data-type="fields" data-callback="rebuild_field_binding" value="<?php echo htmlentities( $conditions_str ); ?>">
271
 
272
- </div>
273
  </div>
274
  <?php
275
  }
@@ -335,7 +374,8 @@ function field_line_template($id = '{{id}}', $label = '{{label}}', $group = '{{g
335
  <a href="#settings-panel"><?php echo __("General Settings", "caldera-forms"); ?></a>
336
  </li>
337
  </ul>
338
- <button class="button button-primary caldera-header-save-button" type="submit"><?php echo __('Update Form', 'caldera-forms'); ?><span id="save_indicator" class="spinner" style="position: absolute; right: -30px;"></span></button>
 
339
  </div>
340
 
341
  <div style="display: none;" class="caldera-editor-body caldera-config-editor-panel " id="settings-panel">
@@ -362,61 +402,77 @@ function field_line_template($id = '{{id}}', $label = '{{label}}', $group = '{{g
362
  </div>
363
  </div>
364
 
 
 
 
 
 
 
 
365
  <div class="caldera-config-group">
366
  <label><?php echo __('Success Message', 'caldera-forms'); ?> </label>
367
  <div class="caldera-config-field">
368
  <input type="text" class="field-config required" name="config[success]" value="<?php echo $element['success']; ?>" style="width:300px;" required="required">
369
  </div>
370
  </div>
371
- <?php do_action('caldera_forms_general_settings_panel'); ?>
372
- </div>
373
-
374
- <?php
375
- // PANELS LOWER NAV
376
-
377
- foreach($panel_extensions as $panel_slug=>$panel){
378
- if(empty($panel['tabs'])){
379
- continue;
380
- }
381
 
382
- ?>
 
383
  <div class="caldera-editor-header caldera-editor-subnav">
384
  <ul class="caldera-editor-header-nav">
385
- <?php
386
- // BUILD ELEMENT SETUP TABS
387
- if(!empty($panel['tabs'])){
388
- // PANEL BASED TABS
389
- foreach($panel['tabs'] as $group_slug=>$tab_setup){
390
- if($tab_setup['location'] !== 'lower'){
391
- continue;
392
- }
393
 
394
- $active = null;
395
- if(!empty($tab_setup['active'])){
396
- $active = " class=\"active\"";
397
- }
398
- echo "<li".$active."><a href=\"#" . $group_slug . "-config-panel\">" . $tab_setup['name'] . "</a></li>\r\n";
399
- }
400
-
401
- // CODE BASED TABS
402
- if(!empty($panel['tabs']['code'])){
403
- foreach($panel['tabs']['code'] as $code_slug=>$tab_setup){
404
- $active = null;
405
- if(!empty($tab_setup['active'])){
406
- $active = " class=\"active\"";
407
- }
408
- echo "<li".$active."><a href=\"#" . $code_slug . "-code-panel\" data-editor=\"" . $code_slug . "-editor\">" . $tab_setup['name'] . "</a></li>\r\n";
409
- }
410
- }
411
 
 
 
 
412
  }
413
 
414
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  </ul>
416
  </div>
417
- <?php
418
- }
419
-
420
 
421
  // PANEL WRAPPERS & RENDER
422
  $repeatable_templates = array();
@@ -661,7 +717,7 @@ do_action('caldera_forms_edit_end', $element);
661
  {{#each lines}}
662
  <div class="caldera-condition-line">
663
  if
664
- <select name="config[{{../type}}][{{../../id}}][conditions][group][{{../id}}][{{id}}][field]" data-condition="{{../type}}" class="caldera-processor-field-bind caldera-conditional-field-set" data-id="{{../../id}}" data-default="{{field}}" data-line="{{id}}" data-row="{{../id}}" data-all="true" style="max-width:120px;"></select>
665
  <select name="config[{{../type}}][{{../../id}}][conditions][group][{{../id}}][{{id}}][compare]" style="max-width:110px;">
666
  <option value="is" {{#is compare value="is"}}selected="selected"{{/is}}><?php echo __('is', 'caldera-forms'); ?></option>
667
  <option value="isnot" {{#is compare value="isnot"}}selected="selected"{{/is}}><?php echo __('is not', 'caldera-forms'); ?></option>
@@ -684,7 +740,7 @@ do_action('caldera_forms_edit_end', $element);
684
  <div class="caldera-condition-line">
685
  <div class="caldera-condition-line-label"><?php echo __('and', 'caldera-forms'); ?></div>
686
  if
687
- <select name="{{name}}[field]" class="caldera-processor-field-bind caldera-conditional-field-set" data-condition="{{type}}" data-id="{{id}}" data-line="{{lineid}}" data-row="{{rowid}}" data-all="true" style="max-width:120px;"></select>
688
  <select name="{{name}}[compare]" style="max-width:110px;">
689
  <option value="is"><?php echo __('is', 'caldera-forms'); ?></option>
690
  <option value="isnot"><?php echo __('is not', 'caldera-forms'); ?></option>
@@ -706,6 +762,33 @@ foreach($field_type_templates as $key=>$template){
706
  echo $template;
707
  echo "\r\n</script>\r\n";
708
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
709
  ?>
710
  <script type="text/javascript">
711
 
@@ -714,6 +797,8 @@ foreach($field_type_templates as $key=>$template){
714
  echo implode("\r\n", $field_type_defaults);
715
 
716
  ?>
 
 
717
  </script>
718
 
719
 
5
  // Load element
6
  $element = get_option( $_GET['edit'] );
7
 
8
+ // build magic tags
9
+ $magic_tags = apply_filters('caldera_forms_get_magic_tags', array());
10
+
11
+ //dump($element);
12
  if(empty($element['success'])){
13
  $element['success'] = __('Form has successfuly been submitted. Thank you.', 'caldera-forms');
14
  }
21
  wp_nonce_field( 'cf_edit_element', 'cf_edit_nonce' );
22
 
23
  // Init check
24
+ echo "<input id=\"last_updated_field\" name=\"config[_last_updated]\" value=\"" . date('r') . "\" type=\"hidden\">";
25
+ echo "<input id=\"form_id_field\" name=\"config[ID]\" value=\"" . $_GET['edit'] . "\" type=\"hidden\">";
26
 
27
  do_action('caldera_forms_edit_start', $element);
28
 
45
  $field_options_template = "
46
  <div class=\"caldera-config-group-toggle-options\">
47
  <div class=\"caldera-config-group caldera-config-group-full\">
48
+ <button type=\"button\" class=\"button add-toggle-option\" style=\"width: 220px;\">" . __('Add Option', 'caldera-forms') . "</button>
49
+ <button type=\"button\" data-bulk=\"#{{_id}}_bulkwrap\" class=\"button add-toggle-option\" style=\"width: 120px;\">" . __('Bulk Insert', 'caldera-forms') . "</button>
50
+ <div id=\"{{_id}}_bulkwrap\" style=\"display:none; margin-top:10px;\">
51
+ <textarea style=\"resize:vertical; height:200px;\" class=\"block-input\" id=\"{{_id}}_batch\"></textarea>
52
+ <p class=\"description\">" . __('Single option per line. These replace the current list.', 'caldera-forms') . "</p>
53
+ <button type=\"button\" data-options=\"#{{_id}}_batch\" class=\"button block-button add-toggle-option\" style=\"margin: 10px 0;\">" . __('Insert Options', 'caldera-forms') . "</button>
54
+ </div>
55
  </div>
56
  <div class=\"caldera-config-group caldera-config-group-full\">
57
  <label style=\"padding: 10px;\"><input type=\"radio\" class=\"toggle_set_default field-config\" name=\"{{_name}}[default]\" value=\"\" {{#unless default}}checked=\"checked\"{{/unless}}> " . __('No Default', 'caldera-forms') . "</label>
58
+ <label class=\"pull-right\" style=\"padding: 10px;\"><input type=\"checkbox\" class=\"toggle_show_values field-config\" name=\"{{_name}}[show_values]\" value=\"1\" {{#if show_values}}checked=\"checked\"{{/if}}> " . __('Show Values', 'caldera-forms') . "</label>
59
+ </div>
60
+ <div class=\"caldera-config-group-option-labels\" {{#unless show_values}}style=\"display:none;\"{{/unless}}>
61
+ <span style=\"display: block; clear: left; padding-left: 65px; float: left; width: 125px;\">" . __('Value', 'caldera-forms') . "</span>
62
+ <span style=\"float: left;\">" . __('Label', 'caldera-forms') . "</span>
63
  </div>
64
  <div class=\"caldera-config-group caldera-config-group-full toggle-options\">
65
  {{#each option}}
66
  <div class=\"toggle_option_row\">
67
  <i class=\"dashicons dashicons-sort\" style=\"padding: 4px 9px;\"></i>
68
  <input type=\"radio\" class=\"toggle_set_default field-config\" name=\"{{../_name}}[default]\" value=\"{{@key}}\" {{#is ../default value=\"@key\"}}checked=\"checked\"{{/is}}>
69
+ <input{{#unless ../show_values}} disabled=\"disabled\" style=\"display:none;\"{{/unless}} type=\"text\" class=\"toggle_value_field field-config\" name=\"{{../_name}}[option][{{@key}}][value]\" value=\"{{value}}\" placeholder=\"value\">
70
+ <input{{#unless ../show_values}} style=\"width:245px;\"{{/unless}} type=\"text\" class=\"toggle_label_field field-config\" name=\"{{../_name}}[option][{{@key}}][label]\" value=\"{{label}}\" placeholder=\"label\">
71
  <button class=\"button button-small toggle-remove-option\" type=\"button\"><i class=\"icn-delete\"></i></button>
72
  </div>
73
  {{/each}}
75
  </div>
76
  ";
77
 
78
+ $default_template = "
79
+ <div class=\"caldera-config-group\">
80
+ <label>Default</label>
81
+ <div class=\"caldera-config-field\">
82
+ <input type=\"text\" class=\"block-input field-config\" name=\"{{_name}}[default]\" value=\"{{default}}\">
83
+ </div>
84
+ </div>
85
+ ";
86
+
87
  // Build Field Types List
88
  foreach($field_types as $field_slug=>$config){
89
 
90
  if(!file_exists($config['file'])){
91
+ if(!function_exists($config['file'])){
92
+ continue;
93
+ }
94
  }
95
  // type list
96
  $categories[] = __('Basic', 'caldera-forms');
130
 
131
  if(empty($config['setup']['preview']) || !file_exists( $config['setup']['preview'] )){
132
 
133
+ // if preview is a function
134
+ if(!empty($config['setup']['preview']) && function_exists($config['setup']['preview'])){
135
+ $func = $config['setup']['preview'];
136
+ $field_type_templates['preview-' . sanitize_key( $field_slug ) . "_tmpl"] = $func($config);
137
+ }else{
138
+ // simulate a preview with actual field file
139
+ $field = array(
140
+ 'label' => '{{label}}',
141
+ 'slug' => '{{slug}}',
142
+ 'type' => '{{type}}',
143
+ 'caption' => '{{caption}}',
144
+ 'config' => (!empty($config['setup']['default']) ? $config['setup']['default'] : array() )
145
+ );
146
+
147
+ $field_name = $field['slug'];
148
+ $field_id = 'preview_fld_' . $field['slug'];
149
+ $field_label = "<label for=\"" . $field_id . "\" class=\"control-label\">" . $field['label'] . "</label>\r\n";
150
+ $field_required = "";
151
+ $field_placeholder = 'placeholder="' . $field['label'] .'"';
152
+ $field_caption = "<span class=\"help-block\">" . $field['caption'] . "</span>\r\n";
153
+
154
+ // blank default
155
+ $field_value = null;
156
+ $field_wrapper_class = "preview-caldera-config-group";
157
+ $field_input_class = "preview-caldera-config-field";
158
+ $field_class = "preview-field-config";
159
+
160
+ ob_start();
161
+ include $config['file'];
162
+ $field_type_templates['preview-' . sanitize_key( $field_slug ) . "_tmpl"] = ob_get_clean();
163
+ }
164
  }else{
165
  ob_start();
166
  include $config['setup']['preview'];
228
  <a href="#<?php echo $id; ?>_conditions_pane" class="button ">Conditions</a>
229
  </div>
230
 
231
+ <h3 class="caldera-editor-field-title"><?php echo $label; ?>&nbsp;</h3>
232
+ <input type="hidden" class="field-config" name="config[fields][<?php echo $id; ?>][ID]" value="<?php echo $id; ?>">
233
  <div id="<?php echo $id; ?>_settings_pane" class="wrapper-instance-pane">
234
  <div class="caldera-config-group">
235
  <label for="<?php echo $id; ?>_type"><?php echo __('Element Type', 'caldera-forms'); ?></label>
240
  ?>
241
  </select>
242
  </div>
243
+ </div>
244
+ <div class="caldera-config-group">
245
+ <label for="<?php echo $id; ?>_fid"><?php echo __('ID', 'caldera-forms'); ?></label>
246
+ <div class="caldera-config-field">
247
+ <input type="text" class="block-input field-id" id="<?php echo $id; ?>_fid" value="<?php echo $id; ?>" readonly="readonly">
248
+ </div>
249
+ </div>
250
+
251
  <div class="caldera-config-group">
252
  <label for="<?php echo $id; ?>_lable"><?php echo __('Name', 'caldera-forms'); ?></label>
253
  <div class="caldera-config-field">
289
  <input type="checkbox" class="field-config field-checkbox" id="<?php echo $id; ?>_entry_list" name="config[fields][<?php echo $id; ?>][entry_list]" value="1" <?php if($entry_list === 1){ echo 'checked="checked"'; }; ?>>
290
  </div>
291
  </div>
 
292
  <div class="caldera-config-field-setup">
293
  </div>
294
  <input type="hidden" class="field_config_string block-input" value="<?php echo htmlentities( $config_str ); ?>">
308
  <?php do_action('caldera_forms_field_conditionals_template', $id); ?>
309
  <input type="hidden" class="field_conditions_config_string block-input ajax-trigger" data-event="none" data-autoload="true" data-request="build_conditions_config" data-template="#conditional-group-tmpl" data-id="<?php echo $id; ?>" data-target="#<?php echo $id; ?>_conditional_wrap" data-type="fields" data-callback="rebuild_field_binding" value="<?php echo htmlentities( $conditions_str ); ?>">
310
 
311
+ </div>
312
  </div>
313
  <?php
314
  }
374
  <a href="#settings-panel"><?php echo __("General Settings", "caldera-forms"); ?></a>
375
  </li>
376
  </ul>
377
+ <button class="button button-primary caldera-header-save-button" data-active-class="none" data-load-element="#save_indicator" type="button"><?php echo __('Update Form', 'caldera-forms'); ?><span id="save_indicator" class="spinner" style="position: absolute; right: -28px;"></span></button>
378
+ <a class="button caldera-header-preview-button" target="_blank" href="<?php echo trailingslashit( get_site_url() ) . '?cf_preview=' . $element['ID']; ?>"><?php echo __('Preview Form', 'caldera-forms'); ?></a>
379
  </div>
380
 
381
  <div style="display: none;" class="caldera-editor-body caldera-config-editor-panel " id="settings-panel">
402
  </div>
403
  </div>
404
 
405
+ <div class="caldera-config-group">
406
+ <label><?php echo __('Hide Form', 'caldera-forms'); ?> </label>
407
+ <div class="caldera-config-field">
408
+ <label><input type="checkbox" class="field-config" name="config[hide_form]" value="1" <?php if(!empty($element['hide_form'])){ ?>checked="checked"<?php } ?>> <?php echo __('Enable', 'caldera-forms'); ?> <?php echo __('Hide form after successful submission', 'caldera-forms'); ?></label>
409
+ </div>
410
+ </div>
411
+
412
  <div class="caldera-config-group">
413
  <label><?php echo __('Success Message', 'caldera-forms'); ?> </label>
414
  <div class="caldera-config-field">
415
  <input type="text" class="field-config required" name="config[success]" value="<?php echo $element['success']; ?>" style="width:300px;" required="required">
416
  </div>
417
  </div>
418
+ <div class="caldera-config-group">
419
+ <label><?php echo __('Gravatar Field', 'caldera-forms'); ?> </label>
420
+ <div class="caldera-config-field">
421
+ <select style="width:300px;" class="field-config caldera-field-bind" name="config[avatar_field]" data-exclude="system" data-default="<?php if(!empty($element['avatar_field'])){ echo $element['avatar_field']; } ?>" data-type="email"></select>
422
+ <p class="description"><?php echo __('Used when viewing an entry from a non-logged in user.','caldera-forms'); ?></p>
423
+ </div>
424
+ </div>
 
 
 
425
 
426
+ <?php do_action('caldera_forms_general_settings_panel', $element); ?>
427
+ </div>
428
  <div class="caldera-editor-header caldera-editor-subnav">
429
  <ul class="caldera-editor-header-nav">
 
 
 
 
 
 
 
 
430
 
431
+ <?php
432
+ // PANELS LOWER NAV
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433
 
434
+ foreach($panel_extensions as $panel_slug=>$panel){
435
+ if(empty($panel['tabs'])){
436
+ continue;
437
  }
438
 
439
  ?>
440
+ <?php
441
+ // BUILD ELEMENT SETUP TABS
442
+ if(!empty($panel['tabs'])){
443
+ // PANEL BASED TABS
444
+ foreach($panel['tabs'] as $group_slug=>$tab_setup){
445
+ if($tab_setup['location'] !== 'lower'){
446
+ continue;
447
+ }
448
+
449
+ $active = null;
450
+ if(!empty($tab_setup['active'])){
451
+ $active = " class=\"active\"";
452
+ }
453
+ echo "<li".$active." id=\"tab_".$group_slug."\"><a href=\"#" . $group_slug . "-config-panel\">" . $tab_setup['name'] . "</a></li>\r\n";
454
+ }
455
+
456
+ // CODE BASED TABS
457
+ if(!empty($panel['tabs']['code'])){
458
+ foreach($panel['tabs']['code'] as $code_slug=>$tab_setup){
459
+ $active = null;
460
+ if(!empty($tab_setup['active'])){
461
+ $active = " class=\"active\"";
462
+ }
463
+ echo "<li".$active."><a href=\"#" . $code_slug . "-code-panel\" data-editor=\"" . $code_slug . "-editor\">" . $tab_setup['name'] . "</a></li>\r\n";
464
+ }
465
+ }
466
+
467
+ }
468
+
469
+ ?>
470
+ <?php
471
+ }
472
+ ?>
473
  </ul>
474
  </div>
475
+ <?php
 
 
476
 
477
  // PANEL WRAPPERS & RENDER
478
  $repeatable_templates = array();
717
  {{#each lines}}
718
  <div class="caldera-condition-line">
719
  if
720
+ <select name="config[{{../type}}][{{../../id}}][conditions][group][{{../id}}][{{id}}][field]" data-condition="{{../type}}" class="caldera-field-bind caldera-conditional-field-set" data-id="{{../../id}}" data-default="{{field}}" data-line="{{id}}" data-row="{{../id}}" data-all="true" style="max-width:120px;"></select>
721
  <select name="config[{{../type}}][{{../../id}}][conditions][group][{{../id}}][{{id}}][compare]" style="max-width:110px;">
722
  <option value="is" {{#is compare value="is"}}selected="selected"{{/is}}><?php echo __('is', 'caldera-forms'); ?></option>
723
  <option value="isnot" {{#is compare value="isnot"}}selected="selected"{{/is}}><?php echo __('is not', 'caldera-forms'); ?></option>
740
  <div class="caldera-condition-line">
741
  <div class="caldera-condition-line-label"><?php echo __('and', 'caldera-forms'); ?></div>
742
  if
743
+ <select name="{{name}}[field]" class="caldera-field-bind caldera-conditional-field-set" data-condition="{{type}}" data-id="{{id}}" data-line="{{lineid}}" data-row="{{rowid}}" data-all="true" style="max-width:120px;"></select>
744
  <select name="{{name}}[compare]" style="max-width:110px;">
745
  <option value="is"><?php echo __('is', 'caldera-forms'); ?></option>
746
  <option value="isnot"><?php echo __('is not', 'caldera-forms'); ?></option>
762
  echo $template;
763
  echo "\r\n</script>\r\n";
764
  }
765
+ ?>
766
+
767
+ <?php
768
+
769
+
770
+ $magic_script = array();
771
+
772
+ foreach($magic_tags as $magic_set_key=>$magic_tags_set){
773
+
774
+ $magic_script[$magic_set_key] = array(
775
+ 'type' => $magic_tags_set['type'],
776
+ 'tags' => array()
777
+ );
778
+
779
+ foreach($magic_tags_set['tags'] as $tag_key=>$tag_value){
780
+
781
+ if(is_array($tag_value)){
782
+ foreach($tag_value as $compatibility){
783
+ $magic_script[$magic_set_key]['tags'][$compatibility][] = $tag_key;
784
+ }
785
+ }else{
786
+ $magic_script[$magic_set_key]['tags']['text'][] = $tag_value;
787
+ }
788
+ }
789
+
790
+ }
791
+
792
  ?>
793
  <script type="text/javascript">
794
 
797
  echo implode("\r\n", $field_type_defaults);
798
 
799
  ?>
800
+ var system_values = <?php echo json_encode( $magic_script ); ?>;
801
+
802
  </script>
803
 
804
 
ui/panels/emailer.php CHANGED
@@ -16,7 +16,7 @@ if(!isset($element['mailer']['email_subject'])){
16
  $element['mailer']['email_subject'] = $element['name'];
17
  }
18
  if(!isset($element['mailer']['email_message'])){
19
- $element['mailer']['email_message'] = '';
20
  }
21
  if(!isset($element['mailer']['enable_mailer'])){
22
  $element['mailer']['enable_mailer'] = '1';
@@ -42,12 +42,14 @@ if(!isset($element['mailer']['enable_mailer'])){
42
  <label><?php echo __('From Name', 'caldera-forms'); ?> </label>
43
  <div class="caldera-config-field">
44
  <input type="text" class="field-config" name="config[mailer][sender_name]" value="<?php echo $element['mailer']['sender_name']; ?>" style="width:400px;">
 
45
  </div>
46
  </div>
47
  <div class="caldera-config-group">
48
  <label><?php echo __('From Email', 'caldera-forms'); ?> </label>
49
  <div class="caldera-config-field">
50
  <input type="text" class="field-config" name="config[mailer][sender_email]" value="<?php echo $element['mailer']['sender_email']; ?>" style="width:400px;">
 
51
  </div>
52
  </div>
53
  <div class="caldera-config-group">
@@ -80,13 +82,14 @@ if(!isset($element['mailer']['enable_mailer'])){
80
  <label><?php echo __('Email Subject', 'caldera-forms'); ?> </label>
81
  <div class="caldera-config-field">
82
  <input type="text" class="field-config" name="config[mailer][email_subject]" value="<?php echo $element['mailer']['email_subject']; ?>" style="width:400px;">
 
83
  </div>
84
  </div>
85
  <div class="caldera-config-group">
86
  <label><?php echo __('Email Message', 'caldera-forms'); ?> </label>
87
  <div class="caldera-config-field" style="max-width: 600px;">
88
  <?php wp_editor( $element['mailer']['email_message'], "mailer_email_message", array('textarea_name' => 'config[mailer][email_message]') ); ?>
89
- <p class="description"><?php echo __('Magic tags, %field_slug% are replaced with submitted data.', 'caldera-forms'); ?></p>
90
  </div>
91
  </div>
92
  </div>
16
  $element['mailer']['email_subject'] = $element['name'];
17
  }
18
  if(!isset($element['mailer']['email_message'])){
19
+ $element['mailer']['email_message'] = '{summary}';
20
  }
21
  if(!isset($element['mailer']['enable_mailer'])){
22
  $element['mailer']['enable_mailer'] = '1';
42
  <label><?php echo __('From Name', 'caldera-forms'); ?> </label>
43
  <div class="caldera-config-field">
44
  <input type="text" class="field-config" name="config[mailer][sender_name]" value="<?php echo $element['mailer']['sender_name']; ?>" style="width:400px;">
45
+ <p class="description"><?php echo __('Use %field_slug% to use a value from the form', 'caldera-forms'); ?></p>
46
  </div>
47
  </div>
48
  <div class="caldera-config-group">
49
  <label><?php echo __('From Email', 'caldera-forms'); ?> </label>
50
  <div class="caldera-config-field">
51
  <input type="text" class="field-config" name="config[mailer][sender_email]" value="<?php echo $element['mailer']['sender_email']; ?>" style="width:400px;">
52
+ <p class="description"><?php echo __('Use %field_slug% to use a value from the form', 'caldera-forms'); ?></p>
53
  </div>
54
  </div>
55
  <div class="caldera-config-group">
82
  <label><?php echo __('Email Subject', 'caldera-forms'); ?> </label>
83
  <div class="caldera-config-field">
84
  <input type="text" class="field-config" name="config[mailer][email_subject]" value="<?php echo $element['mailer']['email_subject']; ?>" style="width:400px;">
85
+ <p class="description"><?php echo __('Use %field_slug% to use a value from the form', 'caldera-forms'); ?></p>
86
  </div>
87
  </div>
88
  <div class="caldera-config-group">
89
  <label><?php echo __('Email Message', 'caldera-forms'); ?> </label>
90
  <div class="caldera-config-field" style="max-width: 600px;">
91
  <?php wp_editor( $element['mailer']['email_message'], "mailer_email_message", array('textarea_name' => 'config[mailer][email_message]') ); ?>
92
+ <p class="description"><?php echo __('Magic tags, %field_slug% are replaced with submitted data. use {summary} to build an automatic mail based on form content. Leaving the mailer blank, will create and automatic summary.', 'caldera-forms'); ?></p>
93
  </div>
94
  </div>
95
  </div>
ui/panels/layout.php CHANGED
@@ -4,11 +4,27 @@ global $field_config_panels;
4
 
5
  // TAKE IN THE GRID
6
 
7
- if(!empty($element['layout_grid']['structure'])){
8
- $rows = explode("|", $element['layout_grid']['structure']);
9
- }else{
10
- $rows = array('12');
11
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  // BUILD TEMPLATE LOCATIONS
14
  $fields = array();
@@ -36,45 +52,66 @@ if(!empty($element['layout_grid']['fields'])){
36
  }
37
  }
38
 
39
-
40
- ?>
41
- <span id="row-remove-fields-message" class="hidden"><?php echo __('This will remove all the fields in this row. Are you sure?', 'caldera-forms'); ?></span>
42
- <div class="layout-grid-panel layout-grid">
43
- <?php
44
- if(!empty($rows)){
45
- foreach($rows as $row=>$columns){ ?>
46
- <div class="first-row-level row">
 
47
  <?php
48
- $row += 1;
49
- $columns = explode(':', $columns);
50
- foreach($columns as $column=>$span){
51
- $column += 1;
52
- ?>
53
- <div class="col-xs-<?php echo $span; ?>">
54
- <div class="layout-column column-container">
55
  <?php
56
 
57
- //render fields here
58
- if(isset($fields[$row][$column])){
59
- foreach($fields[$row][$column] as $field){
60
- ?>
61
- <div class="layout-form-field" data-config="<?php echo $field['ID']; ?>">
62
- <i style="display:none;" class="icon-edit"></i>
63
- <div class="drag-handle">
64
- <div class="field_preview"><span class="spinner" style="display: block; float: left;"></span></div>
 
 
 
 
 
 
 
 
 
 
 
 
65
  </div>
66
- <input type="hidden" class="field-location" value="<?php echo $row.':'.$column; ?>" name="config[layout_grid][fields][<?php echo $field['ID']; ?>]">
67
- </div>
68
- <?php
69
  }
70
- }
71
 
72
- ?>
 
73
  </div>
 
74
  </div>
75
- <?php } ?>
76
- </div>
77
- <?php }} ?>
78
- <!-- Build the grid -->
 
79
  </div>
80
- <input type="hidden" name="config[layout_grid][structure]" class="layout-structure" value="">
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  // TAKE IN THE GRID
6
 
7
+ if(!isset($element['layout_grid']['structure'])){
8
+ $element['layout_grid']['structure'] = '12';
 
 
9
  }
10
+ //dump($element);
11
+ $element['layout_grid']['structure'] = explode("#", $element['layout_grid']['structure']);
12
+
13
+ echo "<span id=\"row-remove-fields-message\" class=\"hidden\">" . __('This will remove all the fields in this row. Are you sure?', 'caldera-forms') . "</span>";
14
+ echo '<div class="toggle_option_tab" data-title="'.__('Page').'" style="float:none;' . ( count($element['layout_grid']['structure']) === 1 ? ' display:none;' : '' ) . '" id="page-toggles">';
15
+ $pgid = uniqid('pg');
16
+ if(count($element['layout_grid']['structure']) >= 1){
17
+ for($i = 1; $i<=count($element['layout_grid']['structure']) ; $i++){
18
+ $name = __('Page') . ' ' . $i;
19
+ if(isset($element['page_names'][($i-1)])){
20
+ $name = htmlspecialchars($element['page_names'][($i-1)]);
21
+ }
22
+ echo '<button type="button" data-page="' . $pgid . $i .'" data-name="' . $name . '" class="page-toggle button' . ( $i === 1 ? ' button-primary' : '' ) . '">' . __('Page') . ' ' . $i . '</button> ';
23
+
24
+ }
25
+ }
26
+ echo '</div>';
27
+ echo "<div id=\"grid-pages-panel\">\r\n";
28
 
29
  // BUILD TEMPLATE LOCATIONS
30
  $fields = array();
52
  }
53
  }
54
 
55
+ $row = 0;
56
+ foreach( (array) $element['layout_grid']['structure'] as $page_key=>$page_struct){
57
+ if(!empty($page_struct)){
58
+ $rows = explode("|", $page_struct);
59
+ }else{
60
+ $rows = array('12');
61
+ }
62
+ ?>
63
+ <div class="layout-grid-panel layout-grid <?php echo ( $page_key === 0 ? 'page-active' : null ); ?>" id="<?php echo $pgid.($page_key+1); ?>" data-page="<?php echo $page_key; ?>" <?php echo ( $page_key > 0 ? ' style="display:none;"' : null ); ?>>
64
  <?php
65
+ if(!empty($rows)){
66
+ foreach($rows as $row_in=>$columns){ ?>
67
+ <div class="first-row-level row">
 
 
 
 
68
  <?php
69
 
70
+ $row += 1;
71
+
72
+ $columns = explode(':', $columns);
73
+ foreach($columns as $column=>$span){
74
+ $column += 1;
75
+ ?>
76
+ <div class="col-xs-<?php echo $span; ?>">
77
+ <div class="layout-column column-container">
78
+ <?php
79
+
80
+ //render fields here
81
+ if(isset($fields[$row][$column])){
82
+ foreach($fields[$row][$column] as $field){
83
+ ?>
84
+ <div class="layout-form-field" data-config="<?php echo $field['ID']; ?>">
85
+ <i style="display:none;" class="icon-edit"></i>
86
+ <div class="drag-handle">
87
+ <div class="field_preview"><span class="spinner" style="display: block; float: left;"></span></div>
88
+ </div>
89
+ <input type="hidden" class="field-location" value="<?php echo $row.':'.$column; ?>" name="config[layout_grid][fields][<?php echo $field['ID']; ?>]">
90
  </div>
91
+ <?php
92
+ }
 
93
  }
 
94
 
95
+ ?>
96
+ </div>
97
  </div>
98
+ <?php } ?>
99
  </div>
100
+ <?php }} ?>
101
+ <!-- Build the grid -->
102
+ <input type="hidden" id="page_structure_<?php echo $page_key; ?>" name="config[layout_grid][structure][]" class="layout-structure" value="">
103
+ </div>
104
+ <?php } ?>
105
  </div>
106
+
107
+ <script type="text/html" id="grid-page-tmpl">
108
+ <div class="layout-grid-panel layout-grid" data-page="{{page_no}}" data-name="<?php echo __('Page'); ?> {{count}}" style="display:none;" id="{{page_no}}">
109
+ <div class="first-row-level row">
110
+ <div class="col-xs-12">
111
+ <div class="layout-column column-container">
112
+ </div>
113
+ </div>
114
+ </div>
115
+ <input type="hidden" id="page_structure_{{page_no}}" name="config[layout_grid][structure][]" class="layout-structure" value="12">
116
+ </div>
117
+ </script>
ui/panels/layout_add_row.php CHANGED
@@ -1,4 +1,14 @@
1
  <a class="add-new-h2 caldera-add-group caldera-add-row" href="#code_panels_tag"><?php echo __('Add Row', 'caldera-forms'); ?></a>
 
 
 
 
 
 
 
 
 
 
2
  <div id="newfield-tool" class="button button-primary button-small layout-new-form-field" title="<?php echo __('Drag onto the form grid below', 'caldera-forms'); ?>">
3
  <i class="icon-edit" style="display:none;"></i>
4
  <i class="dashicons dashicons-menu" style="display:none;"></i>
@@ -7,6 +17,7 @@
7
  <div class="field_preview"></div>
8
  </div><input value="" type="hidden" class="field-location">
9
  </div>
 
10
  <span id="dismiss-add-element" class="ajax-trigger" data-action="cf_dismiss_pointer" data-pointer="add_element"></span>
11
  <?php
12
  $haspointer = get_user_meta( get_current_user_id() , 'cf_pointer_add_element' );
1
  <a class="add-new-h2 caldera-add-group caldera-add-row" href="#code_panels_tag"><?php echo __('Add Row', 'caldera-forms'); ?></a>
2
+ <a class="add-new-h2 caldera-add-group caldera-add-page ajax-trigger"
3
+
4
+ data-addtitle="<?php echo __('Page'); ?>"
5
+ data-template="#grid-page-tmpl"
6
+ data-target-insert="append"
7
+ data-request="add_new_grid_page"
8
+ data-target="#grid-pages-panel"
9
+ data-callback="add_page_grid"
10
+
11
+ href="#code_panels_tag"><?php echo __('Add Page', 'caldera-forms'); ?></a>
12
  <div id="newfield-tool" class="button button-primary button-small layout-new-form-field" title="<?php echo __('Drag onto the form grid below', 'caldera-forms'); ?>">
13
  <i class="icon-edit" style="display:none;"></i>
14
  <i class="dashicons dashicons-menu" style="display:none;"></i>
17
  <div class="field_preview"></div>
18
  </div><input value="" type="hidden" class="field-location">
19
  </div>
20
+
21
  <span id="dismiss-add-element" class="ajax-trigger" data-action="cf_dismiss_pointer" data-pointer="add_element"></span>
22
  <?php
23
  $haspointer = get_user_meta( get_current_user_id() , 'cf_pointer_add_element' );
ui/panels/pages.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="caldera-config-group">
2
+ <label><?php echo __('Progress Bar', 'caldera-forms'); ?></label>
3
+ <div class="caldera-config-field">
4
+ <label><input type="checkbox" name="config[auto_progress]" value="1" <?php if(!empty($element['auto_progress'])){ echo 'checked="checked"'; } ?>> <?php echo __('Show Breadcrumbs', 'caldera-forms'); ?></label>
5
+ <p class="description"><?php echo __('ProTip: Use an HTML element to build a custom progress per page', 'caldera-forms'); ?></p>
6
+ </div>
7
+ </div>
8
+ <div id="page_name_bind">
9
+
10
+ </div>
11
+ <script type="text/html" id="page-name-tmpl">
12
+ <div class="caldera-config-group">
13
+ <label><?php echo __('Page'); ?> {{page_no}}</label>
14
+ <div class="caldera-config-field">
15
+ <input type="text" class="field-config" name="config[page_names][]" value="" style="width:400px;">
16
+ </div>
17
+ </div>
18
+ </script>
19
+ <script>
20
+ jQuery(document).on('add.page remove.page load.page', function(){
21
+
22
+ var pages = jQuery('.page-toggle.button'),
23
+ wrap = jQuery('#page_name_bind'),
24
+ template = jQuery('#page-name-tmpl').html();
25
+
26
+ wrap.empty();
27
+
28
+ pages.each(function(k,v){
29
+ var page = jQuery(v),
30
+ cfg_tmpl = jQuery(template.replace(/{{page_no}}/g, k+1));
31
+
32
+ cfg_tmpl.find('.field-config').val(page.data('name'));
33
+
34
+ cfg_tmpl.appendTo(wrap);
35
+ });
36
+
37
+ });
38
+ </script>
ui/panels/processors.php CHANGED
@@ -4,8 +4,6 @@ global $form_processors;
4
  // Get Processors
5
  $form_processors = apply_filters('caldera_forms_get_form_processors', array() );
6
 
7
- //dump($form_processors,0);
8
-
9
  $form_processors_defaults = array(
10
  "var processor_defaults = {};"
11
  );
@@ -35,17 +33,19 @@ function processor_line_template($id = '{{id}}', $type = null){
35
  <li class="caldera-processor-nav <?php echo $id; ?> <?php if(!empty($type)){ echo 'processor_type_'.$type; }; ?>">
36
  <a href="#<?php echo $id; ?>">
37
  <?php echo $type_name; ?>
 
38
  </a>
 
39
  </li>
40
  <?php
41
  }
42
 
43
- function processor_wrapper_template($id = '{{id}}', $type = null, $config_str = '{"default":"default value"}', $conditions_str = '{"type" : ""}'){
44
 
45
  global $form_processors;
46
 
47
  $type_name = __('New Form Processor', 'caldera-forms');
48
- if(!empty($type)){
49
  if(empty($form_processors[$type])){
50
  return;
51
  }
@@ -92,7 +92,7 @@ function processor_wrapper_template($id = '{{id}}', $type = null, $config_str =
92
  }
93
 
94
  ?>
95
- <div class="caldera-editor-processor-config-wrapper caldera-editor-config-wrapper" id="<?php echo $id; ?>" style="display:none;">
96
  <div class="toggle_option_tab">
97
  <a href="#<?php echo $id; ?>_settings_pane" class="button button-primary">Settings</a>
98
  <a href="#<?php echo $id; ?>_conditions_pane" class="button ">Conditions</a>
@@ -233,7 +233,13 @@ function build_processor_types($default = null){
233
  echo '</span></small>';
234
 
235
  }
236
- echo '<p class="description">' . $processor['description'] . '</p>';
 
 
 
 
 
 
237
  if(!empty($processor['links'])){
238
  echo '<p>';
239
  foreach($processor['links'] as $link){
@@ -251,7 +257,6 @@ function build_processor_types($default = null){
251
 
252
  ?>
253
  </script>
254
-
255
  <script type="text/html" id="processor-line-tmpl">
256
  <?php echo processor_line_template(); ?>
257
  </script>
@@ -260,6 +265,8 @@ function build_processor_types($default = null){
260
  </script>
261
  <?php
262
 
 
 
263
  foreach($form_processors as $processor=>$config){
264
  if(isset($config['template'])){
265
  echo "<script type=\"text/html\" id=\"" . $processor . "-tmpl\">\r\n";
4
  // Get Processors
5
  $form_processors = apply_filters('caldera_forms_get_form_processors', array() );
6
 
 
 
7
  $form_processors_defaults = array(
8
  "var processor_defaults = {};"
9
  );
33
  <li class="caldera-processor-nav <?php echo $id; ?> <?php if(!empty($type)){ echo 'processor_type_'.$type; }; ?>">
34
  <a href="#<?php echo $id; ?>">
35
  <?php echo $type_name; ?>
36
+ <span class="processor-line-number"></span>
37
  </a>
38
+ <input type="hidden" name="config[processors][<?php echo $id; ?>][ID]" value="<?php echo $id; ?>">
39
  </li>
40
  <?php
41
  }
42
 
43
+ function processor_wrapper_template($id = '{{id}}', $type = '{{type}}', $config_str = '{"default":"default value"}', $conditions_str = '{"type" : ""}'){
44
 
45
  global $form_processors;
46
 
47
  $type_name = __('New Form Processor', 'caldera-forms');
48
+ if(!empty($type) && $type != '{{type}}'){
49
  if(empty($form_processors[$type])){
50
  return;
51
  }
92
  }
93
 
94
  ?>
95
+ <div class="caldera-editor-processor-config-wrapper caldera-editor-config-wrapper processor-<?php echo $type; ?>" id="<?php echo $id; ?>" data-type="<?php echo $type; ?>" style="display:none;">
96
  <div class="toggle_option_tab">
97
  <a href="#<?php echo $id; ?>_settings_pane" class="button button-primary">Settings</a>
98
  <a href="#<?php echo $id; ?>_conditions_pane" class="button ">Conditions</a>
233
  echo '</span></small>';
234
 
235
  }
236
+ echo '<p class="description">';
237
+ if(!empty($processor['description'])){
238
+ echo $processor['description'];
239
+ }else{
240
+ echo '&nbsp;';
241
+ }
242
+ echo '</p>';
243
  if(!empty($processor['links'])){
244
  echo '<p>';
245
  foreach($processor['links'] as $link){
257
 
258
  ?>
259
  </script>
 
260
  <script type="text/html" id="processor-line-tmpl">
261
  <?php echo processor_line_template(); ?>
262
  </script>
265
  </script>
266
  <?php
267
 
268
+ do_action('caldera_forms_processor_templates', $form_processors);
269
+
270
  foreach($form_processors as $processor=>$config){
271
  if(isset($config['template'])){
272
  echo "<script type=\"text/html\" id=\"" . $processor . "-tmpl\">\r\n";