-
Notifications
You must be signed in to change notification settings - Fork 0
/
fluid-form.js
126 lines (102 loc) · 3.99 KB
/
fluid-form.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
function FluidForm(wrapper, callback) {
var self = this;
if (typeof wrapper === 'undefined') throw new Error("No reference to a wrapper element passed.");
if (typeof callback !== 'function') throw new Error("No submit callback function passed.");
this.wrapper = wrapper;
this.callback = callback;
this.questions = this.wrapper.find('.fluid-form-question');
this.inputFields = this.wrapper.find(FluidForm.inputFieldsSelector);
this.requiredInputFields = this.inputFields.filter(FluidForm.requiredSelector);
if (this.questions.length === 0) throw new Error("Wrapper element doesn't contain any child elements.");
// next question events
this.wrapper.find('.fluid-form-next-button').on('click', function(e) {
e.stopPropagation();
// button click
self.nextQuestion();
});
this.questions.find('.fluid-form-detect-enter-key').on('keyup change', function(e) {
// enter key
if (e.keyCode === 13) { // enter
self.nextQuestion();
}
});
this.questions.find(FluidForm.inputFieldsSelector).on('keyup change', function() {
if ($(this).val()) {
$(this).removeClass('missing');
}
});
this.wrapper.find('.fluid-form-submit-button').on('click', function(e) {
self.submit();
});
this.questions.on('click', function() {
var index = self.questions.index(this);
if (index === -1 || self.activeIndex === index) return;
// not working for questions which are higher than the screen size
//self.scrollToIndex(index);
});
this.setQuestionIndex(0);
$(window).on('scroll resize', function() { self.handleScrolling(); }).trigger('scroll');
}
FluidForm.scrollOffsetTop = 70;
FluidForm.scrollOffsetBottom = 70;
FluidForm.scrollPaddingTop = 50;
FluidForm.inputFieldsSelector = 'input[type=text], input[type=mail], input[type=number], textarea';
FluidForm.requiredSelector = '[required="required"]';
FluidForm.prototype.activeIndex = 0;
FluidForm.prototype.wrapper = null;
FluidForm.prototype.questions = [];
FluidForm.prototype.nextQuestion = function() {
// check if all required fields are filled
var invalidFieldFound = false;
var inputFields = this.questions.eq(this.activeIndex).find(FluidForm.inputFieldsSelector).filter(FluidForm.requiredSelector);
for (var i = 0; i < inputFields.length; i++) {
if (!inputFields.eq(i).val()) {
invalidFieldFound = true;
inputFields.eq(i).addClass('missing');
}
}
if (invalidFieldFound) return;
// next question available
if (this.questions.length - 1 > this.activeIndex) {
this.scrollToIndex(this.activeIndex + 1);
}
else {
throw new Error("No next question available. Use class .fluid-form-submit-button for the last button.");
}
};
FluidForm.prototype.setQuestionIndex = function(index) {
this.activeIndex = index;
this.questions.removeClass('active');
var newQuestion = this.questions.eq(index);
newQuestion.addClass('active');
newQuestion.find('.fluid-form-autofocus').eq(0).focus();
};
FluidForm.prototype.submit = function() {
for (var i = 0; i < this.requiredInputFields.length; i++) {
if (!this.requiredInputFields.eq(i).val()) {
this.requiredInputFields.eq(i).focus().addClass('missing');
return;
}
}
this.callback();
};
FluidForm.prototype.handleScrolling = function() {
var scrollTop = $(window).scrollTop(), screenHeight = $(window).height();
for (var i = 0; i < this.questions.length; i++) {
var screenMid = scrollTop + screenHeight / 2,
questionTop = this.questions.eq(i).offset().top,
questionBottom = questionTop + this.questions.eq(i).height();
if (questionTop < screenMid && questionBottom > screenMid) {
if (this.activeIndex !== i) {
this.setQuestionIndex(i);
}
break;
}
}
};
FluidForm.prototype.scrollToIndex = function(index) {
$('html, body').animate({ scrollTop: this.questions.eq(index).offset().top + FluidForm.scrollOffsetTop - $(window).height() / 2 }, 1000);
};
FluidForm.prototype.scrollToId = function(id) {
$('html, body').animate({ scrollTop: $('#' + id).offset().top - FluidForm.scrollOffsetTop - FluidForm.scrollPaddingTop }, 1000);
};