Skip to content

Commit c73e7fb

Browse files
Merge pull request #36 from michelegiorgi/development
Release 1.4.1
2 parents 6e13547 + 9d8e00d commit c73e7fb

25 files changed

+485
-412
lines changed

admin/class-formality-admin.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ public function admin_header() {
124124
if(!empty( $update_plugins->response )) {
125125
$updates = array_keys($update_plugins->response);
126126
foreach ($updates as $update) { if($update == 'formality/formality.php') { $updated = false; }}
127-
}
128-
echo '<span class="formality-header-version'. ($updated ? ' updated' : '') .'">' . $this->version . '</span>';
129-
?>
127+
}?>
128+
<span class="formality-header-version<?php echo $updated ? ' updated' : '';?>">
129+
<?php echo $this->version; ?>
130+
<?php if(!$updated) {?><i><?php _e('There is a new version of Formality available', 'formality'); ?></i><?php } ?>
131+
</span>
130132
<?php
131133
if($pagenow == 'edit.php' && $typenow == 'formality_result' && isset($object)) {
132134
if(property_exists($object, 'term_id')) {

assets/scripts/admin.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Formality admin script
22

33
import 'jquery';
4-
import init from './admin/init'
4+
import main from './admin/main'
55
import exports from './admin/export'
66

77
jQuery(document).ready(() => {
8-
init()
8+
main()
99
exports()
1010
});

assets/scripts/admin/export.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const { __ } = wp.i18n
22

3-
43
export default function() {
54

65
let exportToggle = document.querySelector('.formality-export-toggle')
File renamed without changes.

assets/scripts/editor.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// Formality editor scripts
2-
import { pageLoad } from './editor/utility/init.js';
3-
42
import './editor/components/repeaterControl.js';
5-
3+
import { pageLoad } from './editor/utility/init.js';
64
import { formSidebar } from './editor/plugins/sidebar.js';
7-
85
import { textBlock } from './editor/blocks/text.js';
96
import { textareaBlock } from './editor/blocks/textarea.js';
107
import { emailBlock } from './editor/blocks/email.js';
@@ -22,9 +19,7 @@ import { widgetBlock } from './editor/blocks/widget.js';
2219
if(formality.editor=='formality') {
2320

2421
pageLoad()
25-
2622
formSidebar()
27-
2823
textBlock()
2924
textareaBlock()
3025
emailBlock()

assets/scripts/public.js

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
1-
// Formality public scripts
2-
1+
// Formality public script
32
import 'jquery';
4-
import init from './public/init';
53

6-
jQuery(document).ready(() => init());
4+
//core functions
5+
import loader from './public/core/loader'
6+
import uiux from './public/core/uiux'
7+
import nav from './public/core/nav'
8+
import validate from './public/core/validate'
9+
import submit from './public/core/submit'
10+
import conditional from './public/core/conditional'
11+
import embed from './public/core/embed'
12+
import hints from './public/core/hints'
13+
import hooks from './public/core/hooks'
14+
15+
//fields functions
16+
import select from './public/fields/select'
17+
import switch1 from './public/fields/switch'
18+
import textarea from './public/fields/textarea'
19+
import number from './public/fields/number'
20+
import rating from './public/fields/rating'
21+
import multiple from './public/fields/multiple'
22+
import media from './public/fields/media'
23+
import upload from './public/fields/upload'
24+
25+
jQuery(document).ready(() => {
26+
loader.init()
27+
uiux.init()
28+
submit.init()
29+
nav.init()
30+
validate.init()
31+
conditional.init()
32+
embed.init()
33+
hints.init()
34+
35+
select.init()
36+
switch1.init()
37+
textarea.init()
38+
number.init()
39+
rating.init()
40+
multiple.init()
41+
media.init()
42+
upload.init()
43+
});

assets/scripts/public/core/helpers.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export let el = (name, parent = true, child = "") => {
2929
field_success: "formality__field--success",
3030
field_disabled: "formality__field--disabled",
3131
input: "formality__input",
32+
input_status: "formality__input__status",
3233
input_errors: "formality__input__errors",
3334
message: "formality__message",
3435
media: "formality__media",

assets/scripts/public/core/nav.js

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { el, uid } from './helpers'
22
import validate from './validate'
33
import uiux from './uiux'
4-
import emergence from '../vendor/emergence.formality'
54

65
export default {
76
init() {
@@ -127,21 +126,17 @@ export default {
127126
})
128127
},
129128
conversational() {
130-
let emergence_container = document.querySelector('.formality__main');
131-
let emergence_current = 0;
132-
if($("body").hasClass("body-formality")) {
133-
emergence_container = window;
134-
}
135-
emergence.init({
136-
selector: el("field", "uid"),
137-
container: emergence_container,
138-
offsetY: "50%",
139-
callback: function(element, state) {
140-
if (state === 'visible') {
141-
const $el = $(element);
142-
let emergence_active = $el.attr("id");
143-
if(emergence_current!==emergence_active) {
144-
emergence_current = emergence_active;
129+
let container = $("body").hasClass("body-formality") ? null : document.querySelector('.formality__main');
130+
let current = 0;
131+
132+
const sections = document.querySelectorAll(el("field", "uid"));
133+
for (let i = 0; i < sections.length; i++) {
134+
const observer = new IntersectionObserver((entry) => {
135+
if (entry[0].isIntersecting) {
136+
const $el = $(sections[i]);
137+
let active = $el.attr("id");
138+
if(current!==active) {
139+
current = active;
145140
const sended = $el.closest(el("form", true, "--sended")).length
146141
const sectionid = $el.attr("id")
147142
const $navlist = $(el("nav_list", "uid"))
@@ -156,8 +151,9 @@ export default {
156151
}
157152
}
158153
}
159-
},
160-
});
154+
},{ root: container, rootMargin: "-50% 0px" });
155+
observer.observe(sections[i]);
156+
}
161157

162158
$(el("button", "uid", "--mininext")).click(function(e){
163159
let $element = $(el("field_focus")).find(":input")
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import { el, uid } from './helpers'
2+
import 'parsleyjs'
3+
const { __ } = wp.i18n
4+
let fieldOptions = {
5+
text: {
6+
multiple: false,
7+
},
8+
message: {
9+
multiple: false,
10+
},
11+
email: {
12+
multiple: false,
13+
rules: {
14+
email: __("This value should be a valid email", "formality"),
15+
}
16+
},
17+
number: {
18+
multiple: false,
19+
rules: {
20+
number: __("This value should be a valid number", "formality"),
21+
min: /* translators: validation */ __("This value should be greater than or equal to %s", "formality"),
22+
max: /* translators: validation */ __("This value should be lower than or equal to %s", "formality"),
23+
}
24+
},
25+
select: {
26+
multiple: false,
27+
},
28+
multiple: {
29+
multiple: true,
30+
},
31+
rating: {
32+
multiple: true,
33+
},
34+
switch: {
35+
multiple: false,
36+
},
37+
upload: {
38+
multiple: false,
39+
},
40+
}
41+
42+
export default {
43+
init() {
44+
//init validation
45+
$(el("form")).each(function() {
46+
uid($(this))
47+
$(el("section", "uid")).each(function(index, section) {
48+
$(section).find(':input').attr('data-parsley-group', 'step-' + index)
49+
})
50+
})
51+
this.field_error()
52+
this.field_success()
53+
this.form_error()
54+
this.i18n()
55+
$('body').prepend('<button id="testvalidate">Test</button>');
56+
let validate = this;
57+
$('#testvalidate').click(function(){
58+
let form = document.querySelector(el("form"))
59+
validate.validateForm(form)
60+
})
61+
},
62+
checkstep(index, newindex) {
63+
//validate single step
64+
let valid = false
65+
let options = this.parsley_options()
66+
if(index > newindex) {
67+
valid = true
68+
} else {
69+
$(el("form", "uid")).parsley(options).whenValidate({
70+
group: 'step-' + index,
71+
}).done(function() {
72+
valid = true
73+
$(el("nav_section", "uid")).eq(index).addClass(el("nav_section", false, "--validated"))
74+
})
75+
}
76+
return valid
77+
},
78+
form() {
79+
//validate standard form (1 step)
80+
let options = this.parsley_options()
81+
$(el("form", "uid")).parsley(options)
82+
},
83+
parsley_options() {
84+
//create parsley options array
85+
let options = {
86+
classHandler: function (element) {
87+
return element.$element.closest(el("field"))
88+
},
89+
errorClass: el("field_error", false),
90+
errorsContainer: function(element) {
91+
return element.$element.closest(el("input")).find(el("input", true, "__status"))
92+
},
93+
successClass: el("field_success", false),
94+
errorsWrapper: '<ul class="'+el("input_errors", false)+'"></ul>',
95+
}
96+
return options
97+
},
98+
form_error() {
99+
window.Parsley.on('form:error', function() {
100+
101+
})
102+
},
103+
field_error() {
104+
//field error event
105+
window.Parsley.on('field:error', function() {
106+
const id = $(this.$element).attr("id")
107+
uid($(this.$element))
108+
$(el("nav_legend", 'uid', ' li[data-name="' + id + '"]')).addClass("error")
109+
const index = $(el("nav_section", "uid")).index(el("nav_section", "uid", "--active"))
110+
$(el("nav_section", "uid")).eq(index).removeClass(el("nav_section", false, "--validated"))
111+
})
112+
},
113+
field_success() {
114+
//field success event
115+
window.Parsley.on('field:success', function() {
116+
const id = $(this.$element).attr("id")
117+
uid($(this.$element))
118+
$(el("nav_legend", "uid", ' li[data-name="' + id + '"]')).removeClass("error")
119+
})
120+
},
121+
i18n() {
122+
window.Parsley.addMessages('en', {
123+
defaultMessage: __("This value seems to be invalid", "formality"),
124+
type: {
125+
email: __("This value should be a valid email", "formality"),
126+
url: __("This value should be a valid url", "formality"),
127+
number: __("This value should be a valid number", "formality"),
128+
integer: __("This value should be a valid integer", "formality"),
129+
digits: __("This value should be digits", "formality"),
130+
alphanum: __("This value should be alphanumeric", "formality"),
131+
},
132+
required: __("This value is required", "formality"),
133+
pattern: __("This value seems to be invalid", "formality"),
134+
min: /* translators: validation */ __("This value should be greater than or equal to %s", "formality"),
135+
max: /* translators: validation */ __("This value should be lower than or equal to %s", "formality"),
136+
range: /* translators: validation */ __("This value should be between %s and %s", "formality"),
137+
minlength: /* translators: validation */ __("This value is too short. It should have %s characters or more", "formality"),
138+
maxlength: /* translators: validation */ __("This value is too long. It should have %s characters or fewer", "formality"),
139+
length: /* translators: validation */ __("This value length is invalid. It should be between %s and %s characters long", "formality"),
140+
check: /* translators: validation */ __("You must select between %s and %s choices", "formality"),
141+
});
142+
window.Parsley.setLocale('en');
143+
},
144+
checkRule(input, rule) {
145+
let valid = false;
146+
switch(rule) {
147+
case 'required':
148+
if(NodeList.prototype.isPrototypeOf(input)){
149+
Array.prototype.forEach.call(input, function(single, i){ if(single.checked) { valid = true; } })
150+
} else {
151+
valid = input.value !== ''
152+
}
153+
break;
154+
case 'email':
155+
valid = input.value.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
156+
break;
157+
case 'checked':
158+
valid = input.checked;
159+
break;
160+
case 'notchecked':
161+
valid = !input.checked;
162+
break;
163+
}
164+
return valid;
165+
},
166+
validateField(field) {
167+
let validate = this;
168+
const type = field.getAttribute('data-type')
169+
const required = field.classList.contains(el("field", false, "--required"))
170+
let rules = 'rules' in fieldOptions[type] ? Object.keys(fieldOptions[type]['rules']) : []
171+
const multiple = fieldOptions[type]['multiple']
172+
if(required) { rules.unshift('required') }
173+
const input = multiple ? field.querySelectorAll('input, select, textarea') : field.querySelector('input, select, textarea')
174+
const status = field.querySelector(el("input_status"))
175+
let valid = true;
176+
let error = '';
177+
if(!rules.includes('required') && !multiple && !input.value) {
178+
//skip validation
179+
} else {
180+
Array.prototype.forEach.call(rules, function(rule){
181+
if(valid && !validate.checkRule(input, rule)) {
182+
error = rule == 'required' ? __("This value is required", "formality") : fieldOptions[type]['rules'][rule];
183+
valid = false;
184+
}
185+
})
186+
}
187+
field.classList.toggle(el("field", false, "--error"), !valid);
188+
status.innerHTML = !error ? '' : ('<div class="' + el("input_errors", false) + '">' + error + '</div>')
189+
return valid;
190+
},
191+
validateForm(form) {
192+
let validate = this;
193+
let errors = false;
194+
let fields = document.querySelectorAll(el("field"))
195+
let firsterror = false;
196+
Array.prototype.forEach.call(fields, function(field, i){
197+
const error = !validate.validateField(field)
198+
if(!errors && error) {
199+
firsterror = field.querySelector('input, select, textarea')
200+
}
201+
})
202+
if(firsterror) { firsterror.focus() }
203+
return !errors
204+
}
205+
}

0 commit comments

Comments
 (0)