cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <!--PEN CODE-->
<div id="contactForm" class="contactForm">
	<div id="formHeader" class="formHeader">
		<h1 id="message">Contact Me</h1>
	</div>
	<div id="formBody" class="formBody">
		<form action="" method="POST" name="contactForm">
			<div class="inputContainer">
				<label for="userName">
					<i class="fa fa-lg fa-fw fa-user"></i>
				</label>
				<input name="name" id="userName" type="text" placeholder="John Smith">
			</div>
			<div class="inputContainer">
				<label for="userEmail">
					<i class="fa fa-lg fa-fw fa-envelope"></i>
				</label>
				<input name="email" id="userEmail" type="email" placeholder="jsmith@domain.com">
			</div>
			<div class="inputContainer">
				<textarea name="feedback" id="userMessage" rows="10" placeholder="Enter your message"></textarea>
			</div>
			<input id="submitBtn" class="submitBtn" type="submit" value="Send">
		</form>
	</div>
</div>
<center><p><em>NOTE: This form is for presentation only. Any form data entered is not submitted</em></p></center>
<!--END PEN CODE-->
            
          
!
            
              /*PEN STYLES*/

$white: #fff;
$purple: #54428E;
$success: #0A8754;
$lightSuccess: #82E682;
$error: #FF5C5C;
$grey: #ccc;
$opacBlack: rgba(0, 0, 0, 0.3);

@mixin transition($dur, $prop: all, $style: ease) {
	transition: $prop $dur $style;
}
body {
	background: #f1f1f1;
	margin-top: 2rem;
}
.contactForm {
	border-radius: 4px;
	box-sizing: border-box;
	margin: auto;
	max-width: 450px;
	overflow: hidden;

	.formHeader {
		background: $purple;
		border-bottom: 4px solid ($purple / 1.2);
		color: $white;
		text-align: center;
		overflow: hidden;

		/*TRANSITION*/
		@include transition(0.5s);

		h1 {
			line-height: 1em;
		}
	}

	.formBody {
		background: $white;
		// height: 371px;
		padding: 20px 12px;
		overflow: hidden;

		/*TRANSITION*/
		@include transition(0.2s);
	}

	.inputContainer {
		border: 1px solid $grey;
		border-radius: 3px;
		position: relative;
		margin-bottom: 5px;
		overflow: hidden;
		background: transparent;

		.message {
			color: $error;
			background: $error * 2;
			position: absolute;
			top: 0;
			bottom: 0;
			width: 0;
			margin: 0;
			line-height: 2.5em;
			text-align: center;
			overflow: hidden;

			/*TRANSITION*/
			@include transition(0.1s);
		}

		label,
		input,
		textarea {
			box-sizing: border-box;
			padding: 10px;
			font-size: 14px;
			line-height: 1em;
			border: none;
			font: inherit;
		}

		label {
			display: inline-block;
			font-size: .7em;
			background: $grey * 1.1;
			color: $opacBlack;
			line-height: 1.75em;
			border-right: 1px solid $grey;

			/*POSITION*/
			position: absolute;
			left: 0;
			top: 0;
			bottom: 0;
		}

		textarea,
		input {
			width: 100%;
			max-width: 100%;
		}

		textarea {
			margin-bottom: -5px;
		}

		input {
			padding-left: 50px;
		}
	}

	.submitBtn {
		background: $purple;
		color: $white;
		border: none;
		border-radius: 3px;
		font: inherit;
		padding: 10px 18px;
		margin-top: 10px;
		float: right;
		width: auto;

		/*TRANSITION*/
		@include transition(0.5s, background);

		&:hover {
			background: $purple * 1.4;
		}
	}

	/*SUCESS STYLES*/
	&.success {
		overflow: hidden;

		.formHeader {
			background: $success;
			border-color: $success / 1.2;
			font-size: .75em;
		}

		.formBody {
			height: 0;
			padding-top: 0;
			padding-bottom: 0;

			form {
				/*TRANSITION*/
				@include transition(0.5s, opacity);

				opacity: 0;
			}
		}
	}

	.inputContainer.success {
		border-color: $lightSuccess / 1.1;

		&:after {
			font: 1.25em/2em FontAwesome;
			color: $lightSuccess;
			position: absolute;
			top: 0;
			right: 10px;
			content: "\f00c";
		}

		label {
			background: $lightSuccess;
			border-color: $lightSuccess / 1.1;
		}

		input,
		textarea {
			color: $success;
		}
	}

	.inputContainer.error {
		border-color: $error / 1.1;

		.message {
			width: 100%;
		}

		&:after {
			font: 1.25em/2em FontAwesome;
			color: $error;
			position: absolute;
			top: 0;
			right: 10px;
			content: "\f00d";
		}
		label {
			background: $error;
			border-color: $error / 1.1;
		}

		input,
		textarea {
			color: $error;
		}
	}
}

            
          
!
            
              (function() {
	"use strict";
	var //GLOBAL VARIABLES
	input,
			container,
			//CSS CLASSES
			classSuccess = "success",
			classError = "error",
			//FORM VALIDATOR
			formValidator = {
				init: function() {
					this.cacheDom();
					this.bindEvents();
				},
				cacheDom: function() {
					//MAIN PARENT ELEMENT
					this.contactForm = document.getElementById("contactForm");
					//MAIN FORM ELEMENTS
					this.formHeader = document.querySelector("#formHeader h1");
					this.formBody = document.getElementById("formBody");
					this.inputContainer = document.getElementsByClassName("inputContainer");
					//USER INPUT ELEMENTS
					//INPUT FIELDS
					this.fields = {
						userName: document.getElementById("userName"),
						userEmail: document.getElementById("userEmail"),
						userMessage: document.getElementById("userMessage")
					};
					this.submitBtn = document.getElementById("submitBtn");
				},
				bindEvents: function() {
					var i;
					//RUN RULES ON SUBMIT BUTTON CLICK
					this.submitBtn.onclick = this.runRules.bind(this);
					//BIND EVENTS TO EACH INPUT FIELD
					for (i in this.fields) {
						if (this.fields.hasOwnProperty(i)) {
							//VARIABLES
							input = this.fields[i];
							container = input.parentElement;
							//RUN RULES WHEN INPUT HAS FOCUS
							input.onfocus = this.runRules.bind(this);
							//RESET ERRORS WHEN CONTAINER IS CLICKED
							container.onclick = this.resetErrors.bind(this, input);
						}
					}
				},
				runRules: function(evnt) {
					var target = evnt.target,
							type = evnt.type;
					//IF EVENT ON SUBMIT BUTTON
					if (target === this.submitBtn) {
						//PREVENT FORM SUBMITTION
						this.preventDefault(evnt);
						//IF INPUT HAS FOCUS
					} else if (type === "focus") {
						//RESET CLASSLIST
						this.resetClassList(target.parentElement);
						//RESET ERRORS
						this.resetErrors(target);
						return false;
					}
					//RESET CLASSLIST
					this.resetClassList();
					//CHECK FIELDS
					this.checkFields();
				},
				preventDefault: function(evnt) {
					//PREVENT DEFUALT
					evnt.preventDefault();
				},
				checkFields: function() {
					var i,
							validCount = 0,
							//EMAIL FILTER 
							filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
					//CYLCE THROUGH INPUTS
					for (i in this.fields) {
						if (this.fields.hasOwnProperty(i)) {
							input = this.fields[i];
							//CHECK IF FIELD IS EMPTY
							if (input.value === "") {
								//ADD ERROR CLASS
								this.addClass(input, classError);
								//CHECK IF EMAIL IS VALID
							} else if (i === "userEmail" && !filter.test(input.value)) {
								//ADD ERROR CLASS
								this.addClass(input, classError);
							} else {
								//FIELD IS VALID
								this.addClass(input, classSuccess);
								validCount += 1;
							}
						}
					}
					//IF ALL FEILDS ARE VALID
					if (validCount === 3) {
						//SUBMIT FORM
						this.submitForm();
					}
				},
				addClass: function(input, clss) {
					container = input.parentElement;
					//IF INPUT HAS ERROR
					if (clss === classError) {
						//SHOW ERROR MESSAGE
						this.errorMessage(input);
					}
					//ADD CLASS
					input.parentElement.classList.add(clss);
				},
				errorMessage: function(input) {
					var message;
					//IF USERNAME HAS ERROR
					if (input === this.fields.userName) {
						message = "Please enter your name";
						//ELSE IF USEREMAIL HAS ERROR 
					} else if (input === this.fields.userEmail) {
						message = "Please enter a valid email";
						//ELSE IF USERMESSAGE HAS ERROR
					} else if (input === this.fields.userMessage) {
						message = "Please enter your feedback";
					}
					this.renderError(input, message);
				},
				renderError: function(input, message) {
					var html;
					//GET INPUT CONTAINER
					container = input.parentElement;
					//RENDER HTML
					html = document.createElement("div");
					html.setAttribute("class", "message");
					html.innerHTML = message;
					//IF MESSAGE ELEMENT DOESN'T EXIST
					if (!container.getElementsByClassName("message")[0]) {
						//INSERT MESSAGE TO INPUT CONTAINER
						container.insertBefore(html, container.firstElementChild);
					}
				},
				resetClassList: function(input) {
					var i;
					//IF TARGETING SPECIFIC INPUT
					if (input) {
						//GET INPUT CONTAINER
						container = input.parentElement;
						//REMOVE CLASSES
						container.classList.remove(classError, classSuccess);
						//FOCUS ON INPUT FIELD
						input.focus();
					} else {
						for (i in this.fields) {
							if (this.fields.hasOwnProperty(i)) {
								//REMOVE CLASSES FROM ALL FIELDS
								this.fields[i].parentElement.classList.remove(classError, classSuccess);
							}
						}
					}
				},
				resetErrors: function(input) {
					//GET INPUT CONTAINER
					container = input.parentElement;
					//IF CONTAINER CONTAINS ERROR
					if (container.classList.contains(classError)) {
						//RESET CLASSES
						this.resetClassList(input);
					}
				},
				submitForm: function() {
					var waitForAnimation;
					//ADD SUCCESS CLASS
					this.contactForm.classList.add(classSuccess);
					//WAIT FOR ANIMATION TO FINISH
					this.changeHeader("Sent Succesfully");
					//WAIT FOR ANIMATION TO FINISH
					setTimeout(this.changeHeader.bind(this, "Thank you for your feedback"), 1200);
				},
				changeHeader: function(text) {
					//CHANGE HEADER TEXT
					this.formHeader.innerHTML = text;
				}
			};
	//INITIATE FORM VALIDATOR
	formValidator.init();
}());
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console