PageSourceSearch

http://www.antoine.tv/site2016/js/vendor/newsletter.js

js antoine.tv collected 2026-10-02 08:04:15 UTC 6,398 bytes, 236 lines download raw bytes

1/**
2 * stepsForm.js v1.0.0
3 * http://www.codrops.com
4 *
5 * Licensed under the MIT license.
6 * http://www.opensource.org/licenses/mit-license.php
7 * 
8 * Copyright 2014, Codrops
9 * http://www.codrops.com
10 */
11;( function( window ) {
12	
13	'use strict';
14
15	var transEndEventNames = {
16			'WebkitTransition': 'webkitTransitionEnd',
17			'MozTransition': 'transitionend',
18			'OTransition': 'oTransitionEnd',
19			'msTransition': 'MSTransitionEnd',
20			'transition': 'transitionend'
21		},
22		transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
23		support = { transitions : Modernizr.csstransitions };
24
25	function extend( a, b ) {
26		for( var key in b ) { 
27			if( b.hasOwnProperty( key ) ) {
28				a[key] = b[key];
29			}
30		}
31		return a;
32	}
33
34	function stepsForm( el, options ) {
35		this.el = el;
36		this.options = extend( {}, this.options );
37  		extend( this.options, options );
38  		this._init();
39	}
40
41	stepsForm.prototype.options = {
42		onSubmit : function() { return false; }
43	};
44
45	stepsForm.prototype._init = function() {
46		// current question
47		this.current = 0;
48
49		// questions
50		this.questions = [].slice.call( this.el.querySelectorAll( 'ol.questions > li' ) );
51		// total questions
52		this.questionsCount = this.questions.length;
53		// show first question
54		classie.addClass( this.questions[0], 'current' );
55		
56		// next question control
57		this.ctrlNext = this.el.querySelector( 'button.next' );
58
59		// progress bar
60		this.progress = this.el.querySelector( 'div.progress' );
61		
62		// question number status
63		this.questionStatus = this.el.querySelector( 'span.number' );
64		// current question placeholder
65		this.currentNum = this.questionStatus.querySelector( 'span.number-current' );
66		this.currentNum.innerHTML = Number( this.current + 1 );
67		// total questions placeholder
68		this.totalQuestionNum = this.questionStatus.querySelector( 'span.number-total' );
69		this.totalQuestionNum.innerHTML = this.questionsCount;
70
71		// error message
72		this.error = this.el.querySelector( 'span.error-message' );
73		
74		// init events
75		this._initEvents();
76	};
77
78	stepsForm.prototype._initEvents = function() {
79		var self = this,
80			// first input
81			firstElInput = this.questions[ this.current ].querySelector( 'input' ),
82			// focus
83			onFocusStartFn = function() {
84				firstElInput.removeEventListener( 'focus', onFocusStartFn );
85				classie.addClass( self.ctrlNext, 'show' );
86			};
87
88		// show the next question control first time the input gets focu
88sed
89		firstElInput.addEventListener( 'focus', onFocusStartFn );
90
91		// show next question
92		this.ctrlNext.addEventListener( 'click', function( ev ) { 
93			ev.preventDefault();
94			self._nextQuestion(); 
95		} );
96
97		// pressing enter will jump to next question
98		document.addEventListener( 'keydown', function( ev ) {
99			var keyCode = ev.keyCode || ev.which;
100			// enter
101			if( keyCode === 13 ) {
102				ev.preventDefault();
103				self._nextQuestion();
104			}
105		} );
106
107		// disable tab
108		this.el.addEventListener( 'keydown', function( ev ) {
109			var keyCode = ev.keyCode || ev.which;
110			// tab
111			if( keyCode === 9 ) {
112				ev.preventDefault();
113			} 
114		} );
115	};
116
117	stepsForm.prototype._nextQuestion = function() {
118		if( !this._validade() ) {
119			return false;
120		}
121
122		// check if form is filled
123		if( this.current === this.questionsCount - 1 ) {
124			this.isFilled = true;
125		}
126
127		// clear any previous error messages
128		this._clearError();
129
130		// current question
131		var currentQuestion = this.questions[ this.current ];
132
133		// increment current question iterator
134		++this.current;
135
136		// update progress bar
137		this._progress();
138
139		if( !this.isFilled ) {
140			// change the current question number/status
141			this._updateQuestionNumber();
142
143			// add class "show-next" to form element (start animations)
144			classie.addClass( this.el, 'show-next' );
145
146			// remove class "current" from current question and add it to the next one
147			// current question
148			var nextQuestion = this.questions[ this.current ];
149			classie.removeClass( currentQuestion, 'current' );
150			classie.addClass( nextQuestion, 'current' );
151		}
152
153		// after animation ends, remove class "show-next" from form element and change current question placeholder
154		var self = this,
155			onEndTransitionFn = function( ev ) {
156				if( support.transitions ) {
157					this.removeEventListener( transEndEventName, onEndTransitionFn );
158				}
159				if( self.isFilled ) {
160					self._submit();
161				}
162				else {
163					classie.removeClass( self.el, 'show-next' );
164					self.currentNum.innerHTML = self.nextQuestionNum.innerHTML;
165					self.questionStatus.removeChild( self.nextQuestionNum );
166					// force the focus on the next input
167					nextQuestion.querySelector( 'input' ).focus();
168				}
169			};
170
171		if( support.transitions ) {
172			this.progress.addEventListener( transEndEventName, onEndTransitionFn );
173		}
174		else {
175			onEndTransitionFn();
176		}
177	}
178
179	// updates the progress bar by setting its width
180	stepsForm.prototype._progress = function() {
181		this.progress.style.width = this.current * ( 100 / this.questionsCount ) + '%';
182	}
183
184	// changes the current question number
185	stepsForm.prototype._updateQuestionNumber = function() {
186		// first, create next question number placeholder
187		this.nextQuestionNum = document.createElement( 'span' );
188		this.nextQuestionNum.className = 'number-next';
189		this.nextQuestionNum.innerHTML = Number( this.current + 1 );
190		// insert it in the DOM
191		this.questionStatus.appendChild( this.nextQuestionNum );
192	}
193
194	// submits the form
195	stepsForm.prototype._submit = function() {
196		this.options.onSubmit( this.el );
197	}
198
199	// TODO (next version..)
200	// the validation function
201	stepsForm.prototype._validade = function() {
202		// current question´s input
203		var input = this.questions[ this.current ].querySelector( 'input' ).value;
204		if( input === '' ) {
205			this._showError( 'EMPTYSTR' );
206			return false;
207		}
208
209		return true;
210	}
211
212	// TODO (next version..)
213	stepsForm.prototype._showError = function( err ) {
214		var message = '';
215		switch( err ) {
216			case 'EMPTYSTR' : 
217				message = 'Please fill the field before continuing';
218				break;
219			case 'INVALIDEMAIL' : 
220				message = 'Please fill a valid email address';
221				break;
222			// ...
223		};
224		this.error.innerHTML = message;
225		classie.addClass( this.error, 'show' );
226	}
227
228	// clears/hides the current error message
229	stepsForm.prototype._clearError = function() {
230		classie.removeClass( this.error, 'show' );
231	}
232
233	// add to global namespace
234	window.stepsForm = stepsForm;
235
236})( window );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.