Fancy Sliding Form with jQuery

Today we are going to create a fancy sliding form that shows some validation feedback to the user after each step. This form saves a lot of space and is […]

From our sponsor: Try Mailchimp today.

Today we are going to create a fancy sliding form that shows some validation feedback to the user after each step. This form saves a lot of space and is easy to access – it basically works like a slide show, just that we have fieldsets of a form instead of images.

So let’s start!

The Markup

The HTML will consist of a wrapper container where we will place a form with fieldsets. Each fieldset will be a step in our sliding form:

<h1>Fancy Sliding Form with jQuery</h1>
<div id="wrapper">
	<div id="steps">
		<form id="formElem" name="formElem" action="" method="post">
			<fieldset class="step">
				<legend>Account</legend>
				<p>
					<label for="username">User name</label>
					<input id="username" name="username" />
				</p>
				<p>
					<label for="email">Email</label>
					<input id="email" name="email" type="email" />
				</p>
				<p>
					<label for="password">Password</label>
					<input id="password" name="password" type="password" />
				</p>
			</fieldset>
			<fieldset>
			...
			</fieldset>
		</form>
	</div>
	<div id="navigation" style="display:none;">
		<ul>
			<li class="selected">
				<a href="#">Account</a>
			</li>
			<li>
				<a href="#">Personal Details</a>
			</li>
			<li>
				<a href="#">Payment</a>
			</li>
			<li>
				<a href="#">Settings</a>
			</li>
			<li>
				<a href="#">Confirm</a>
			</li>
		</ul>
	</div>
</div>

The navigation with all the links to the steps will be an unordered list that is initially hidden. We will show it in our JavaScript function.
Let’s look at the style.

The CSS

The main wrapper and the steps container will have the following style:

#wrapper{
    -moz-box-shadow:0px 0px 3px #aaa;
    -webkit-box-shadow:0px 0px 3px #aaa;
    box-shadow:0px 0px 3px #aaa;
    -moz-border-radius:10px;
    -webkit-border-radius:10px;
    border-radius:10px;
    border:2px solid #fff;
    background-color:#f9f9f9;
    width:600px;
    overflow:hidden;
}
#steps{
    width:600px;
    overflow:hidden;
}
.step{
    float:left;
    width:600px;
}

The class step will be given to each fieldset. Let’s style the navigation:

#navigation{
    height:45px;
    background-color:#e9e9e9;
    border-top:1px solid #fff;
    -moz-border-radius:0px 0px 10px 10px;
    -webkit-border-bottom-left-radius:10px;
    -webkit-border-bottom-right-radius:10px;
    border-bottom-left-radius:10px;
    border-bottom-right-radius:10px;
}
#navigation ul{
    list-style:none;
	float:left;
	margin-left:22px;
}
#navigation ul li{
	float:left;
    border-right:1px solid #ccc;
    border-left:1px solid #ccc;
    position:relative;
	margin:0px 2px;
}

The single link elements will have a neat CSS3 gradient as background:

#navigation ul li a{
    display:block;
    height:45px;
    background-color:#444;
    color:#777;
    outline:none;
    font-weight:bold;
    text-decoration:none;
    line-height:45px;
    padding:0px 20px;
    border-right:1px solid #fff;
    border-left:1px solid #fff;
    background:#f0f0f0;
    background:
        -webkit-gradient(
        linear,
        left bottom,
        left top,
        color-stop(0.09, rgb(240,240,240)),
        color-stop(0.55, rgb(227,227,227)),
        color-stop(0.78, rgb(240,240,240))
        );
    background:
        -moz-linear-gradient(
        center bottom,
        rgb(240,240,240) 9%,
        rgb(227,227,227) 55%,
        rgb(240,240,240) 78%
        )
}
#navigation ul li a:hover,
#navigation ul li.selected a{
    background:#d8d8d8;
    color:#666;
    text-shadow:1px 1px 1px #fff;
}

When a step get’s validated, we will either add a span indicating that everything is fine, or a span that shows that something is wrong in the form step:

span.checked{
    background:transparent url(../images/checked.png) no-repeat top left;
    position:absolute;
    top:0px;
    left:1px;
    width:20px;
    height:20px;
}
span.error{
    background:transparent url(../images/error.png) no-repeat top left;
    position:absolute;
    top:0px;
    left:1px;
    width:20px;
    height:20px;
}

The styles for the form elements look as follows:

#steps form fieldset{
    border:none;
    padding-bottom:20px;
}
#steps form legend{
    text-align:left;
    background-color:#f0f0f0;
    color:#666;
    font-size:24px;
    text-shadow:1px 1px 1px #fff;
    font-weight:bold;
    float:left;
    width:590px;
    padding:5px 0px 5px 10px;
    margin:10px 0px;
    border-bottom:1px solid #fff;
    border-top:1px solid #d9d9d9;
}
#steps form p{
    float:left;
    clear:both;
    margin:5px 0px;
    background-color:#f4f4f4;
    border:1px solid #fff;
    width:400px;
    padding:10px;
    margin-left:100px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    -moz-box-shadow:0px 0px 3px #aaa;
    -webkit-box-shadow:0px 0px 3px #aaa;
    box-shadow:0px 0px 3px #aaa;
}
#steps form p label{
    width:160px;
    float:left;
    text-align:right;
    margin-right:15px;
    line-height:26px;
    color:#666;
    text-shadow:1px 1px 1px #fff;
    font-weight:bold;
}
#steps form input:not([type=radio]),
#steps form textarea,
#steps form select{
    background: #ffffff;
    border: 1px solid #ddd;
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    outline: none;
    padding: 5px;
    width: 200px;
    float:left;
}
#steps form input:focus{
    -moz-box-shadow:0px 0px 3px #aaa;
    -webkit-box-shadow:0px 0px 3px #aaa;
    box-shadow:0px 0px 3px #aaa;
    background-color:#FFFEEF;
}
#steps form p.submit{
    background:none;
    border:none;
    -moz-box-shadow:none;
    -webkit-box-shadow:none;
    box-shadow:none;
}
#steps form button {
	border:none;
	outline:none;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
    color: #ffffff;
    display: block;
    cursor:pointer;
    margin: 0px auto;
    clear:both;
    padding: 7px 25px;
    text-shadow: 0 1px 1px #777;
    font-weight:bold;
    font-family:"Century Gothic", Helvetica, sans-serif;
    font-size:22px;
    -moz-box-shadow:0px 0px 3px #aaa;
    -webkit-box-shadow:0px 0px 3px #aaa;
    box-shadow:0px 0px 3px #aaa;
    background:#4797ED;
}
#steps form button:hover {
    background:#d8d8d8;
    color:#666;
    text-shadow:1px 1px 1px #fff;
}

And now, let’s add some JavaScript magic!

The JavaScript

In our function we will first take care of the display of the slider. For that we need to calculate the width of the elements inside. We will also take care of the sliding when we tab through the inputs. When the user hits tab when he is in the last input of a fieldset, we make the next fieldset slide into place and focus on the first field.

The validation of the form is based on all inputs being required fields. If we slide to the next fieldset and did not fill out all the inputs of the previous one, we will mark the missing inputs with a red background and add our little error span to the navigation item. If everything was fine, we will add the span with the check mark so that the user knows, the step was correct. We will not allow the user to submit the form if one of the steps contains errors.

$(function() {
	/*
	number of fieldsets
	*/
	var fieldsetCount = $('#formElem').children().length;

	/*
	current position of fieldset / navigation link
	*/
	var current 	= 1;

	/*
	sum and save the widths of each one of the fieldsets
	set the final sum as the total width of the steps element
	*/
	var stepsWidth	= 0;
    var widths 		= new Array();
	$('#steps .step').each(function(i){
        var $step 		= $(this);
		widths[i]  		= stepsWidth;
        stepsWidth	 	+= $step.width();
    });
	$('#steps').width(stepsWidth);

	/*
	to avoid problems in IE, focus the first input of the form
	*/
	$('#formElem').children(':first').find(':input:first').focus();	

	/*
	show the navigation bar
	*/
	$('#navigation').show();

	/*
	when clicking on a navigation link
	the form slides to the corresponding fieldset
	*/
    $('#navigation a').bind('click',function(e){
		var $this	= $(this);
		var prev	= current;
		$this.closest('ul').find('li').removeClass('selected');
        $this.parent().addClass('selected');
		/*
		we store the position of the link
		in the current variable
		*/
		current = $this.parent().index() + 1;
		/*
		animate / slide to the next or to the corresponding
		fieldset. The order of the links in the navigation
		is the order of the fieldsets.
		Also, after sliding, we trigger the focus on the first
		input element of the new fieldset
		If we clicked on the last link (confirmation), then we validate
		all the fieldsets, otherwise we validate the previous one
		before the form slided
		*/
        $('#steps').stop().animate({
            marginLeft: '-' + widths[current-1] + 'px'
        },500,function(){
			if(current == fieldsetCount)
				validateSteps();
			else
				validateStep(prev);
			$('#formElem').children(':nth-child('+ parseInt(current) +')').find(':input:first').focus();
		});
        e.preventDefault();
    });

	/*
	clicking on the tab (on the last input of each fieldset), makes the form
	slide to the next step
	*/
	$('#formElem > fieldset').each(function(){
		var $fieldset = $(this);
		$fieldset.children(':last').find(':input').keydown(function(e){
			if (e.which == 9){
				$('#navigation li:nth-child(' + (parseInt(current)+1) + ') a').click();
				/* force the blur for validation */
				$(this).blur();
				e.preventDefault();
			}
		});
	});

	/*
	validates errors on all the fieldsets
	records if the form has errors in $('#formElem').data()
	*/
	function validateSteps(){
		var FormErrors = false;
		for(var i = 1; i < fieldsetCount; ++i){
			var error = validateStep(i);
			if(error == -1)
				FormErrors = true;
		}
		$('#formElem').data('errors',FormErrors);
	}

	/*
	validates one fieldset
	and returns -1 if errors found, or 1 if not
	*/
	function validateStep(step){
		if(step == fieldsetCount) return;

		var error = 1;
		var hasError = false;
		$('#formElem').children(':nth-child('+ parseInt(step) +')').find(':input:not(button)').each(function(){
			var $this 		= $(this);
			var valueLength = jQuery.trim($this.val()).length;

			if(valueLength == ''){
				hasError = true;
				$this.css('background-color','#FFEDEF');
			}
			else
				$this.css('background-color','#FFFFFF');
		});
		var $link = $('#navigation li:nth-child(' + parseInt(step) + ') a');
		$link.parent().find('.error,.checked').remove();

		var valclass = 'checked';
		if(hasError){
			error = -1;
			valclass = 'error';
		}
		$('<span class="'+valclass+'"></span>').insertAfter($link);

		return error;
	}

	/*
	if there are errors don't allow the user to submit
	*/
	$('#registerButton').bind('click',function(){
		if($('#formElem').data('errors')){
			alert('Please correct the errors in the Form');
			return false;
		}
	});
});

And that’s it! I hope you liked the sliding form idea!

Message from TestkingGet professional testking ccda training to learn about critical web design tools and become expert in web design using testking mcts tutorials and testking mcitp live demos.

Tagged with:

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 183

Comments are closed.
  1. I’ve implemented this great jQuery form into a new book website that I’m doing, but having issues with it in IE7. I’ve read through the discussion comments and a couple have suggested putting a blank div tag at the end of the form…I have tried this and it still doesn’t fix the issue of the height. What it’s doing is putting the “Confirm” step below the second to last setps which makes the overall height twice as tall. Any suggestions as to how to fix this issue? I viewed the demo and it’s the same way.

    http://www.couragebeforeeverydanger.com/order/order.html

    Also is there a way to make it so not every single field is required? My form consist of a couple fields I don’t necessarily want to have required as some may not want to provide the information (i.e. phone number).

    Thanks,
    Cody

  2. Do you not want all the fields required? I’ve figured out a way to allow you the ability to specify which fields get marked as required.

    On “sliding.form.js” find line 110. Then locate “find(‘:input:not(button)’).
    Change that section to “find(‘:input.required:not(button)’).

    Adding the “.required” puts a class that it searches for on the inputs. So on your form put [class=”required”] – w/o brackets – on each of the fields/inputs you want to be required.

    Hope this helps you, I was sure glad to figure it out!

  3. Solution for optional

    update your .html
    add optional=”optional”

    update sliding.form.js
    add 3 lines
    112. var optional = $this.attr( ‘optional’ );
    113. if (optional != ‘optional’){
    122. }


    $(‘#formElem’).children(‘:nth-child(‘+ parseInt(step) +’)’).find(‘:input:not(button)’).each(function(){
    var $this = $(this);
    var optional = $this.attr( ‘optional’ );
    if (optional != ‘optional’){
    var valueLength = jQuery.trim($this.val()).length;

    if(valueLength == ”){
    hasError = true;
    $this.css(‘background-color’,’#FFEDEF’);
    }
    else
    $this.css(‘background-color’,’#FFFFFF’);
    }
    });


    GOOD LUCKY

  4. Hello, I do not understand and send this form to my mail. Could you explain? Sorry for my bad English. Thanks

  5. ML, I implemented your form to my page as a quote request form for my clients. It works great but I’m having a small issue that I can’t sort out. If I used tab to go through the form when it jumps to the second window, half the bottom buttons disappear and if I keep pressing tab eventually all the bottom buttons disappear. I’m not sure where I went wrong. I’ve tried fixing it using tabindex but it doesn’t make a difference. Can you check out my form at http://www.inkkings.com/quote.cfm? I’d really appreciate your help. Thanks in advance.

    • @Randy, sorry for just answering now, did you solve the issue? I was trying to recreate the problem on your website but everything seems to be fine now. Cheers, ML

  6. @ML, no I’m still having the issue. I’m seeing it with Safari and Firefox. I haven’t tested on IE yet. Thanks.

  7. Hey I have one question that I hope it will be answered…Is there any way I can store the step (fieldset) I was before after posting? So instead of returning back to the first step I would return to the last shown step after refres or posting?

  8. @ML. Sorry to bug you about this but its one of the final elements i need to finish my site. I tested on IE and IE9 beta and im gettin different errors on IE than on safari and firefox. The form doesnt seem to respond appropriately using the bottom navigation buttons. Sometimes it doesnt do anything at all. Id be willing to pay if you could help me sort everything out. Thanks

  9. Forget about the post submitted earlier (# ines
    September 16th, 2010 at 07:57 ). I have managed to do exactly what I wanted… Thanks anyway 😉

  10. How can I fix the issue with the 2 end steps? In your demo “Settings” and “Confirm” are being displayed together… please help ASAP! Thank you!

  11. I’m using IE7 but I supouse that browser is not the problem…
    There is a demo on cibercafe when all works fine…

  12. haha love how its called Fancy Sliding. This is used for soooo many sites now. More like played out sliding. But great guide for anyone getting into it.

  13. MARY LOU, I will thank your help… I love this jQuery effect!

    With the same browser IE7 the mastercafe demo is working fine… the last 2 steps are not in the same window

  14. We are trying to add the arrows navigation like the image but we can’t get it… have you any code for do that please? Thank you!

  15. Great form!!
    I too am trying to add the arrow navigation (or at least a “Next Step” button) to make it a little more user friendly. I would appreciate any help. If I find a solution I will post also. Thanks!!

  16. @ML. I got the issues sorted out. Problem was the last input field has to be an input not a select or something else. Also using multiple select was causing errors. Not sure why but I removed it and it works great now.

  17. The form is very nice, but is poorly validated. For example, you enter a letter in the mail and I will validate correctly. The same applies to a numeric field, you write a letter and it validates correctly.

  18. @Lord, we did not intend to create any validation for this form, merely an example for how to show validation feedback to the user. You have to add your custom validation for each field, client and server side. Cheers, ML

  19. Sure wish this form would work correctly in IE 7. The navigation doesn’t show up correctly, I have to made the height 900 before it shows, but then when using the tab keys to fill out the form it messes the location of the fields so by the third slide you can hardly see any portion of it. The creator had a great idea, but hasn’t thoroughly tested cross-browser compatibility. Looks like others are experience the same issues or at least issue with IE 7. Being a web designer myself I can understand the frustration of cross-browser compatibility. I recommend a fix gets implemented or else a notice is placed in the article stating that it’s incompatible with IE 7. If anyone has ideas as to how to get it fixed please let me know.

    Thanks,
    Cody

    • Dear Cody, I see your frustration, do you want your money back? 🙂
      On Codrops we try really hard to create innovative things and share them in the form of tutorials with our readers. Believe me, there wouldn’t be ANY innovation if we would develop all our things with IE7 compatibility in our heads. And no, I will not place any notice about IE7 because first, it’s completely outdated, and second, this is a web development site that does not offer ready baked solutions but ideas and guides on how you as a web developer can implement things. We will always try our best create cross browser compatible things but hey, you have to at least turn on the oven, right? 🙂 Cheers, Mary Lou (the creator)

  20. For MAJ + Tab on first input:

    $fieldset.find(“:input:first”).keydown(function(e){
    if (e.which == 9 && e.shiftKey == true){
    $(‘#navigation li:nth-child(‘ + (parseInt(current)-1) + ‘) a’).click();
    /* force the blur for validation */
    $(this).blur();
    e.preventDefault();
    }
    });

  21. i want to validate my selected fields and not want to validate my any seleced tab also ?

  22. Putting a blank div tag with class name “step” at the end of the form will fix IE issue. ie wrapping of last div “confirm”.

    like this:

  23. Does anyone know how to get Radio Buttons to Validate? When I add a radio group to my form, and make a selection in the group, the form doesn’t seem to know that a selection has been made. Please advise.

  24. Mary Lou,

    First of all, I absolutely love your idea here. It looks fantastic and I’m totally planning on using it.

    I made a few modifications to the javascript file that fixes a few problems I can see, and some that uses suggested. I have solved the alt tab/going back issue, added validation on the submit button in case there is a reset button and the form was filled out properly, but in the end was reset and submitted.

    I have also freed the javascript from being intertwined with the html. Now in order to apply the javascript the form needs to have a class attribute set. The navigation is automatically inserted based on the legend text in each section. I also added the class=”required” suggestion on the code.

    I would have just sent the files to you, but your email address is understandably nowhere to be found. If you want to email me I’ll send you the updated js, css, and html files. I’ve tested in FF 3.6.12 and IE 8.0.6001.

    -brian

  25. Brian, until Mary Lou gets back to you, could you not publish your modified code on your own website with a link here in the comments (or if links are not allowed just the site name and page with a gap between each part instead of dots)? Obviously you should acknowledge this page and link to it from your site.

    That way we can experiment further to see if it helps in some situations.

    PS I think this style of form is great.

  26. Dear All,

    Warmest Regards.

    How can i add inline validation for fields. eg:
    1) email validation.
    2) name cannot have any special character.

    Please advise.

    Thank you.

    Regards,
    Micheale

  27. Browser compatibility

    In IE7 last field-set is not working properly….please help me

  28. This is how I amake a field not required to validate:

    function validateStep(step){
    if(step == fieldsetCount) return;

    var error = 1;
    var hasError = false;
    $(‘#formElem’).children(‘:nth-child(‘+ parseInt(step) +’)’).find(‘:input:not(button)’).each(function(){
    var $this = $(this);
    var valueLength = jQuery.trim($this.val()).length;
    if($(this).hasClass(‘nocheck’)){
    hasError = false;
    }
    else {
    if(valueLength == ”){
    hasError = true;
    $this.css(‘background-color’,’#FFEDEF’);
    }
    else {
    $this.css(‘background-color’,’#FFFFFF’);
    }}
    });

    var $link = $(‘#navigation li:nth-child(‘ + parseInt(step) + ‘) a’);
    $link.parent().find(‘.error,.checked’).remove();

    var valclass = ‘checked’;
    if(hasError){
    error = -1;
    valclass = ‘error’;
    }
    $(”).insertAfter($link);

    return error;
    }

    Then add class ‘nocheck’ to the input

  29. Hi very nice but I have some problem with .

    I want something like this:

    and text.
    But it doesn’t line up the text shows somewhere else in the page. How do I solve this?

  30. Hi very nice but I have some problem with select.

    I want something like this:

    label for select and select text.
    But it doesn’t line up the text shows somewhere else in the page. How do I solve this?

  31. Hi,

    I have an input with type=hidden it only shows up when a certain item is selected. Unfortunatly the hidden input never gets validated only when it shows up and data is entered.

    I tried Ramin’s solution but that didn’t work for me. It validates all the fields and the slider is gone. Please tell me how do I fix this?

  32. This is a great form tutorial. Thanks for your explanation.

    Is there a way to add a ‘Continue’ or ‘Prev’/’Next’ buttons to the bottom of each screen that will simulate clicking the appropriate tab?

    I am concerned that my users will not understand to click the tab to move to the next available set of fields.

    Thanks,
    -DJ

  33. Hi, its realy great form, thanks very much!

    if i change the direction to rtl all the look get wrong… do u have any suggestion?
    (sorry about my english…)

    Thank you.

    Regards,
    Daniel

  34. it’s great
    i want to disable tab which will be enable when user click a checkbox
    How can i do that
    i appreciate ur response

  35. First of all, I love this use of jQuery! Very awesome.

    I am having a small issue with tabbing through items, though. It seems to happen when the last item in a frameset is a select or checkbox (only two ive noticed it happen with). It causes the navigation to offset to the left about half way, as well as only bring over the next frameset half way.

    Has anyone had this issue and found a fix?

  36. Hi Mary Lou,
    Great work , thaks v much.
    Is there any way to have other form elements in i.e. radios? I can’t seem to get the validation working when radios are in.
    Thanks in advance.
    D

  37. great tutorial thanks a lot.
    how can i change the height of the sliding form.

  38. HI.it’s really great. but i have a problem. how can i connect it to mysql database? i want to save the users information in mysql database.
    please help me. thank you.