alt-web logo

Tips & Tutorials for Web Designers

Wednesday, October 21, 2015

Timeline with Bootstrap and Tabbed Panels

LIVE DEMO
Timeline preview
Screenshot
Here's the Code:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Timeline</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

<!--Bootstrap-->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<style>
.center-block { float: none }
.nav-tabs li > a { font-size: 26px }
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-10 center-block">
<h1>Timeline Demo</h1>
<p>Coded with Bootstrap &amp; Tabbed Panels</p>

<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#menu1"><span class="glyphicon glyphicon-arrow-right"></span>2001</a></li>
<li><a data-toggle="tab" href="#menu2"><span class="glyphicon glyphicon-arrow-right"></span>2004</a></li>
<li><a data-toggle="tab" href="#menu3"><span class="glyphicon glyphicon-arrow-right"></span>2007</a></li>
<li><a data-toggle="tab" href="#menu4"><span class="glyphicon glyphicon-arrow-right"></span>2010</a></li>
<li><a data-toggle="tab" href="#menu5"><span class="glyphicon glyphicon-arrow-right"></span>2015</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in active" id="menu1">
<h3>Some Event in 2001:</h3>
<div class="col-sm-6">
<img class="img-thumbnail" src="http://lorempixel.com/400/300/people/1" alt="...">
</div>
<div class="col-sm-6">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Mauris vitae libero lacus, vel hendrerit nisi!  Maecenas quis velit nisl, volutpat viverra felis.</p>
<p>Vestibulum luctus mauris sed sem dapibus luctus.  Pellentesque aliquet aliquet ligula, et sagittis justo auctor varius. Quisque varius scelerisque nunc eget rhoncus.  Aenean tristique enim ut ante dignissim.</p>
<p><a class="btn btn-info btn-lg"href="http://example.com">MORE INFO</a></p>
</div>
</div>
<div class="tab-pane fade" id="menu2">
<h3>Some Event in 2004:</h3>
<div class="col-sm-6">
<img class="img-thumbnail" src="http://lorempixel.com/400/300/people/2" alt="...">
</div>
<div class="col-sm-6">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Mauris vitae libero lacus, vel hendrerit nisi!  Maecenas quis velit nisl, volutpat viverra felis.</p>
<p>Vestibulum luctus mauris sed sem dapibus luctus.  Pellentesque aliquet aliquet ligula, et sagittis justo auctor varius. Quisque varius scelerisque nunc eget rhoncus.  Aenean tristique enim ut ante dignissim.</p>
<p><a class="btn btn-info btn-lg"href="http://example.com">MORE INFO</a></p>
</div>
</div>
<div class="tab-pane fade" id="menu3">
<h3>Some Event in 2007:</h3>
<div class="col-sm-6">
<img class="img-thumbnail" src="http://lorempixel.com/400/300/people/3" alt="...">
</div>
<div class="col-sm-6">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Mauris vitae libero lacus, vel hendrerit nisi!  Maecenas quis velit nisl, volutpat viverra felis.</p>
<p>Vestibulum luctus mauris sed sem dapibus luctus.  Pellentesque aliquet aliquet ligula, et sagittis justo auctor varius. Quisque varius scelerisque nunc eget rhoncus.  Aenean tristique enim ut ante dignissim.</p>
<p><a class="btn btn-info btn-lg"href="http://example.com">MORE INFO</a></p>
</div>
</div>
<div class="tab-pane fade" id="menu4">
<h3>Some Event in 2010:</h3>
<div class="col-sm-6">
<img class="img-thumbnail" src="http://lorempixel.com/400/300/people/4" alt="...">
</div>
<div class="col-sm-6">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Mauris vitae libero lacus, vel hendrerit nisi!  Maecenas quis velit nisl, volutpat viverra felis.</p>
<p>Vestibulum luctus mauris sed sem dapibus luctus.  Pellentesque aliquet aliquet ligula, et sagittis justo auctor varius. Quisque varius scelerisque nunc eget rhoncus.  Aenean tristique enim ut ante dignissim.</p>
<p><a class="btn btn-info btn-lg"href="http://example.com">MORE INFO</a></p>
</div>
</div>
<div class="tab-pane fade" id="menu5">
<h3>Some Event in 2015:</h3>
<div class="col-sm-6">
<img class="img-thumbnail" src="http://lorempixel.com/400/300/people/5" alt="...">
</div>
<div class="col-sm-6">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Mauris vitae libero lacus, vel hendrerit nisi!  Maecenas quis velit nisl, volutpat viverra felis.</p>
<p>Vestibulum luctus mauris sed sem dapibus luctus.  Pellentesque aliquet aliquet ligula, et sagittis justo auctor varius. Quisque varius scelerisque nunc eget rhoncus.  Aenean tristique enim ut ante dignissim.</p>
<p><a class="btn btn-info btn-lg"href="http://example.com">MORE INFO</a></p>
</div>
</div>
<!--end tabs-->
</div>
</div>
</div>
</div>
<!--Latest jQuery Core Library-->
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<!--Bootstrap JS-->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">
</script>
</body>
</html>


LIVE DEMO

Wednesday, August 5, 2015

Responsive Videos in Bootstrap 3

Bootstrap has a nice set of classes for embedding responsive videos and preserving their aspect ratios in multiple device widths.

Embedded 4:3 Responsive Aspect Ratio (YouTube video)
<div class="embed-responsive embed-responsive-4by3">
<iframe class="embed-responsive-item" src="//www.youtube.com/embed/ePbKGoIGAXY"></iframe>
</div>


Embedded 16:9 Responsive Aspect Ratio (YouTube video)
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="//www.youtube.com/embed/ePbKGoIGAXY"></iframe>
</div>


But what if you're not using an <iframe> from YouTube, etc... ?  No worries.  It still works a treat!  Simply add the embed-responsive-item to your <video> tag.   BTW, thanks to techslides.com for the sample video.

4:3 Responsive Aspect Ratio (your MP4 video)
<div class="embed-responsive embed-responsive-4by3">
<video autoplay loop class="embed-responsive-item">
<!--replace this sample with your video-->
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
</video>

</div>


16:9 Responsive Aspect Ratio (your MP4 video)
<div class="embed-responsive embed-responsive-16by9">
<video autoplay loop class="embed-responsive-item">
<!--replace this sample with your video-->
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
</video>


Adding Overlays and Captions to Responsive Videos

I had a client who wanted to use his looping video sequence as a background layer, add a semi-opaque overlay and some text that would actually rescale with the responsive video.  Ouch!  My initial idea was to use a poster-image but that didn't meet all the requirements.  So back to the drawing board...

Long story short, I decided to use a figure caption. Why a figcaption you ask?  Why not?!  It's certainly semantic.  With some creative CSS code and a font-size expressed in VW - Viewport Width instead of pixels, it will do exactly what I need in all but the hopelessly inferior browsers (bad browsers, you know who you are).

CSS Code:

.overlay figcaption {
    position: absolute;
    z-index: 1000;
    height: 100%;
    width: 100%;
    background: rgba(0,0,0,0.6);
    /**text, adjust as req'd**/
    padding-top: 15%;
    padding-left: 5%;
    color: #FFF;
    font-weight: 700;
    text-align: center;
    font-size: 20px; /**some fallback value**/
    font-size: 5.4vw; /**responsive size**/
}


If you're all new to Viewport Units here are some links.
http://caniuse.com/
https://css-tricks.com/

Below is the revised HTML markup with figures:

4:3 Responsive Aspect Ratio with Figcaption
<div class="embed-responsive embed-responsive-4by3">
<figure class="overlay">
<video autoplay loop class="embed-responsive-item">
<!--replace this sample with your video-->
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
</video>

<figcaption>figcaption<br>
Lorem ipsum dolor<br>
<a href="http://example.com" class="btn btn-lg btn-info">Learn more</a></figcaption>
</figure>

</div>


16:9 Responsive Aspect Ratio with Figcaption
<div class="embed-responsive embed-responsive-16by9">
<figure class="overlay">
<video autoplay loop class="embed-responsive-item">
<!--replace this sample with your video-->
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
</video>

<figcaption>figcaption<br>
Lorem ipsum dolor<br>
<a href="http://example.com" class="btn btn-lg btn-info">Learn more</a></figcaption>
</figure>

</div>


LIVE DEMO
This is a screenshot at mobile width.
Responsive Aspect Ratio
I hope you enjoyed this introduction to Bootstrap's responsive video classes and CSS viewport units.



Saturday, August 1, 2015

Customizing Bootstrap's Carousel

By default, Bootstrap's Carousel component slides from right to left which is certainly fine for most projects that need a slider.  Below is the default code for it.  UPDATED for Bootstrap 3.3.6.  By the way, my thanks to Lorempixel for the images.

LIVE DEMO

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Bootstrap Default Carousel</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--Bootstrap-->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<header class="row">
<h1>Bootstrap 3.3.6 Carousel Default Settings</h1>
</header>
</div>
<!--begin Bootstrap Carousel-->
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li>
</ol>
<!-- Wrapper for items and captions -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="http://lorempixel.com/1200/400/sports/4/" alt="...">
<div class="carousel-caption">
<h3>Image 1</h3>
<p>Details....</p></div>
</div>
<div class="item">
<img src="http://lorempixel.com/1200/400/sports/3/" alt="...">
<div class="carousel-caption">
<h3>Image 2</h3>
<p>Details....</p>
</div>
</div>
<div class="item">
<img src="http://lorempixel.com/1200/400/sports/2/" alt="...">
<div class="carousel-caption">
<h3>Image 3</h3>
<p>Details....</p>
</div>
</div>
<div class="item">
<img src="http://lorempixel.com/1200/400/sports/1/" alt="...">
<div class="carousel-caption">
<h3>Image 4</h3>
<p>Details....</p>
</div>
</div>
<!--end active-->
</div>
<!-- Left and right controls -->
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a>
<!--end carousel-->
</div>
<!--Latest jQuery Core Library-->
<script src="http://code.jquery.com/jquery-latest.min.js">
</script>
<!--Bootstrap-->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>


For a recent project, I needed a FADE transition and I wanted image captions and text to NOT be  centered over my slides.

My custom CSS code:

<style>
@charset "utf-8";
/**Bootstrap Carousel FADE**/
.carousel img {width:100%}

.carousel-caption {
background-color: rgba(0,0,0,0.5);
position: absolute;
right: 0;
bottom: 0px;
left: 0;
z-index: 10;
padding-top: 0;
padding-bottom: 0px;
color: #fff;
text-align: left;
padding-left: 2%;
}
.carousel-caption h3 {
font-family: Cambria, "Hoefler Text", "Liberation Serif", Times, "Times New Roman", serif;
letter-spacing: -1px;
font-size: 24px;
font-weight: bold;
margin-bottom: 0;
margin-top: 6px !important;
text-align: left;
text-shadow: 2px 1px 2px rgba(0,0,0,0.9);
}
.carousel-caption p {
margin-top: 0;
font-size: 14px;
text-align: left;
}
.carousel-control { width: /*15%*/ 8% }
.carousel-indicators { bottom: 2px }
.carousel-indicators .active { background: #FDF7DE }

/**arrows**/
.carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-prev, .carousel-control .icon-next {
width: 25px;
height: 25px;
font-size: 25px;
}
.carousel-fade .carousel-inner .item {
opacity: 0;
transition-property: opacity;
}
.carousel-fade .carousel-inner .active {
opacity: 1;
}
.carousel-fade .carousel-inner .active.left,
.carousel-fade .carousel-inner .active.right {
left: 0;
opacity: 0;
z-index: 1;
}
.carousel-fade .carousel-inner .next.left,
.carousel-fade .carousel-inner .prev.right {
opacity: 1;
}
.carousel-fade .carousel-control {
z-index: 2;
}
/*WHAT'S NEW IN BS 3.3: Added transforms to improve carousel performance in modern browsers. now override the 3.3 new styles for modern browsers & apply opacity*/
@media all and (transform-3d), (-webkit-transform-3d) {
.carousel-fade .carousel-inner > .item.next, .carousel-fade .carousel-inner > .item.active.right {
opacity: 0;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.carousel-fade .carousel-inner > .item.prev, .carousel-fade .carousel-inner > .item.active.left {
opacity: 0;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.carousel-fade .carousel-inner > .item.next.left, .carousel-fade .carousel-inner > .item.prev.right, .carousel-fade .carousel-inner > .item.active {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
</style>


And finally, I added the carousel-fade class and a data-interval to myCarousel HTML code.  Incidentally, if you set the data-interval value to "0", the slides do not rotate automatically.  If you want a faster slide rotation, use a lower value.  For slower rotation, use a higher value.

<div id="myCarousel" class="carousel slide carousel-fade" data-ride="carousel" data-interval="7000">

FINAL LIVE DEMO


Friday, July 31, 2015

Server-Side Includes with PHP

How can I have the same navigation menu on a multi-page web site?

This question gets asked a lot in web design & development forums.  I like to use Server-Side Includes for this because they are powerful, flexible and efficient.

Let's say you have a 20 page web site that uses the same navigation menu on all pages.  When it comes time to edit your menus, you must open all 20 pages, make changes, save them and then upload all 20 pages to your web server.  Talk about tedious not to mention error prone...

Now what if you could open just one file, edit, save & upload it? Voila!  New menu automatically populates to all your web pages.  That's exactly what SSIs can do.  And more.  They are perfect for sitewide headers, footers and other global elements that you frequently use in your sites.

So let's get started with SSIs

NOTE: For this to work you must save your web pages with a .php file extension and your server must support PHP scripts.  If unsure, ask your web hosting provider.

What are Server-Side Includes? 
Small files that contain code fragments.  They are not complete web pages mind you, instead they are just bits of relevant HTML code.

The default HTML markup for a basic nav might look something like this.  Notice there is no doc type, <html>, <head>, <style>, <body> or other markup here.  It is just the menu code and nothing more.

<nav>
<ul>
<li><a href="#">Menu Item 1</a></li>
<li><a href="#">Menu Item 2</a></li>
<li><a href="#">Menu Item 3</a></li>
<li><a href="#">Menu Item 4</a></li>
<li><a href="#">Menu Item 5</a></li>   
</ul>
</nav>


Or if you use Bootstrap, your navbar code might look more like this.

<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">BRAND</a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">MENU 1</a></li>
<li><a href="#">MENU 2</a></li>
<li><a href="#">MENU 3</a> </li>
<li><a href="#">MENU 4</a> </li>
<li><a href="#">MENU 5</a></li>
 </ul>
</div>
</nav>


#1 Create an Include file:
Open your main web page (index.html), cut and paste your current nav code into a blank text file.   You can save the include file as ANYTHING you wish:
  • nav.htm
  • navbar.html
  • menu.ssi
  • top-nav.php
  • menu.txt
  • nav_menu.foo
  • filename.whatever
It doesn't matter what you call the include file.   Although for this tutorial, I'm saving my file inside an Includes folder and naming it menu.html.

#2 Insert a Server-Side Include Statement:
Now go back to your main page and replace the empty space where your menu was with a Server-side Include Statement.  This is a little bit of PHP code that calls the include file into your web page.

<!--menu goes here-->
<?php require_once('Includes/menu.html'); ?>


#3 Save index.html as index.php
To parse PHP includes in web pages, it's best to name your web pages with .php extension. Upload both files to your server to test -- menu.html  & index.php.
Be sure to remove the old index.html file from your server.

Repeat Steps #2 and #3 for remaining site pages.

How can I test pages in my local browser? 
You will need a local testing server.  Get one of the following Apache servers for your OS and follow the installation instructions (5 min set-up).

WAMP for Windows
http://www.wampserver.com/en/

XAMPP for Windows
http://www.apachefriends.org/en/xampp-windows.html

XAMPP for Mac
http://www.apachefriends.org/en/xampp-macosx.html

MAMP for Mac
http://www.mamp.info/en/downloads/index.html

Can I parse Includes in ordinary .html files?
This varies by web host.  Some shared hosting plans allow it but many do not.  If you're on a dedicated or VPS hosting plan, it's likely that you can parse .html files as .php files by amending (or creating) an .htaccess file in your server's root folder.  If unsure, check with your hosting provider.

Contents of .htaccess file:

AddType text/html .php
AddHandler server-parsed .php
Options Indexes FollowSymLinks Includes
AddHandler server-parsed .html


A word or two about link paths in server-side include files.  
The link paths to site pages are relative to the main page in which Server-Side Include Statements occur.   For example, if you keep all your site pages at root level, you won't have any problems.  But if you save your site pages to various levels in sub- or sub-sub-folders, you will encounter problems with dead links. To avoid this, convert your include file's links to absolute paths -- http://yourdomain.com/folder/filename.php

That's all there is to it. We hope you enjoyed this introduction to Server-Side Includes with PHP. The more you use them, the more uses you will find for them. 

Monday, July 27, 2015

Responsive Contact Form with Bootstrap 3.2 and PHP (Part 3)

If you stumbled on to this page from a search engine, I highly recommend first reading:
In Part 3 of this tutorial, we will add Error and Success reporting to our responsive contact form.  If you have been following along, this is the combined PHP & HTML5 code you should have in your document thus far.

 <?php
// NOTE: this page must be saved as a .php file.
// And your server must support PHP 5.3+ PHP Mail().
// Define variables and set to empty values
$result = $name = $email = $phone = $message = $human = "";
$errName = $errEmail = $errPhone = $errMessage = $errHuman = "";
    if (isset($_POST["submit"])) {
        $name = $_POST['name'];
        $email = $_POST['email'];
        $phone = $_POST['phone'];
        $message = $_POST['message'];
        $human = intval($_POST['human']);
         //valid address on your web server
        $from = 'webmaster@yourdomain.com ';
        //your email address where you wish to receive mail
        $to = 'you@yourdomain.com';
        $subject = 'MESSAGE FROM YOUR WEB SITE';
        $headers = "From:$from\r\nReply-to:$email";
        $body = "From: $name\n E-Mail: $email\n Phone: $phone\n Message: $message";
// Check if name is entered
if (empty($_POST["name"])) {
$errName = "Please enter your name.";
} else {
    $name = test_input($_POST["name"]);
}
// Check if email is entered
if (empty($_POST["email"])) {
$errEmail = "Please enter your email address.";
} else {
    $email = test_input($_POST["email"]);
    // check if e-mail address is valid format
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      $errEmail = "Invalid email format.";
    }
}
// Check if phone is entered although it is not required so we don't need error message
if (empty($_POST["phone"])) {
$phone = "";
} else {
    $phone = test_input($_POST["phone"]);
}
//Check if message is entered
if (empty($_POST["message"])) {
$errMessage = "Please enter your message.";
} else {
    $message = test_input($_POST["message"]);
}
//Check if simple anti-bot test is entered
if (empty($_POST["human"])) {
$errHuman = "Please enter the sum.";
} else {
     if ($human !== 12) {
     $errHuman = 'Wrong answer. Please try again.';
        }
}
// If there are no errors, send the email & output results to the form
if (!$errName && !$errEmail && !$errPhone &&  !$errMessage && !$errHuman) {
    if (mail ($to, $subject, $body, $from)) {
        $result='<div class="alert alert-success"><h2><span class="glyphicon glyphicon-ok"></span> Message sent!</h2><h3>Thank you for contacting us. Someone will be in touch with you soon.</h3></div>';
    } else {
        $result='<div class="alert alert-danger"><h2><span class="glyphicon glyphicon-warning-sign"></span> Sorry there was a form processing error.</h2> <h3>Please try again later.</h3></div>';
       }
    }
}
//sanitize data inputs  
function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   $data = (filter_var($data, FILTER_SANITIZE_STRING));
   return $data;
}
//end form processing script
?>

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Bootstrap Form and PHP Script</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--Bootstrap-->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<style>
.required {color:red; font-weight:bold}
.center-block {float:none}
.human {margin: 0 0 0 12px}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="col-md-8 center-block">
<h3>Responsive Contact Form</h3>
<p class="required small">* = Required fields</p>
<!--begin HTML Form-->
<form class="form-horizontal" role="form" method="post" action=" ">
<div class="form-group">
<label for="name" class="col-sm-3 control-label"><span class="required">*</span> Name:</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="name" name="name" placeholder="First & Last">
</div>
</div>
<div class="form-group">
<label for="email" class="col-sm-3 control-label"><span class="required">*</span> Email: </label>
<div class="col-sm-9">
<input type="email" class="form-control" id="email" name="email" placeholder="you@domain.com">
</div>
</div>
<div class="form-group">
<label for="phone" class="col-sm-3 control-label">Phone: </label>
<div class="col-sm-9">
<input type="tel" class="form-control" id="phone" name="phone" placeholder="(123) 456-7890">
</div>
</div>
<div class="form-group">
<label for="message" class="col-sm-3 control-label"><span class="required">*</span> Message:</label>
<div class="col-sm-9">
<textarea class="form-control" row="4" name="message" placeholder="Tell us your story"></textarea>

</div>
</div>
<div class="form-group">
<label for="human" class="col-sm-3 control-label"><span class="required">*</span> Human Test:</label>
<div class="col-sm-4">
<h3 class="human">6 + 6 = ?</h3>
<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6 col-sm-offset-3">
<button type="submit" id="submit" name="submit" class="btn-lg btn-primary btn-block">SUBMIT</button>
</div>
</div>
<!--end Form--></form>
<!--end col block--></div>
<!--end col--></div>
<!--end row--></div>
<!--end container--></div>
<!--Latest jQuery Core Library-->
<script src="http://code.jquery.com/jquery-latest.min.js">
</script>
<!--Bootstrap-->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>



The form action attribute is empty.  If our script was in a separate file, we could call it with  action="some_script.php"  but since we have put our script directly into the contact page, we don't need to call a separate file.   Instead we will use PHP_SELF to execute this script.  For security reasons, we will filter html characters so hackers can't exploit this form by typing a bogus URL and code in the address bar. So here is the code:

<!--begin HTML Form-->
<form class="form-horizontal" role="form" method="post" action="
<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">


Next, we need to add a placeholder for Bootstrap's Error or Success Alert messages to appear when the form is submitted.  Add this entire block under the opening <form> tag.

<!--when submit button is clicked, show results here-->
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">

<?php echo $result;?>
</div>
</div>


We also need to show the data values inside the form input fields and if data is missing, we will show the error message under the missing field inside <span> tags.  Let's start with the name input field.

<input type="text" class="form-control" id="name" name="name" placeholder="First & Last" value="<?php echo $name;?>">
<span class="required small"><?php echo $errName;?></span>


Repeat this for the remaining input fields - email, phone, message and human (bot-test).

<input type="email" class="form-control" id="email" name="email" placeholder="you@domain.com" value="<?php echo $email;?>">
<span class="required small"><?php echo $errEmail;?></span>



<input type="tel" class="form-control" id="phone" name="phone" placeholder="(123) 456-7890" value="<?php echo $phone;?>">
<span class="required small"><?php echo $errPhone;?></span>



<textarea class="form-control" row="4" name="message" placeholder="Tell us your story"><?php echo $message;?></textarea>
<span class="required small"><?php echo $errMessage;?></span>



<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer" value="<?php echo $human;?>">
<span class="required small"><?php echo $errHuman;?></span>


Completed Form

If you've followed my instructions to the letter, your form and processing script should be working properly when you upload it to your remote server and test it.  Pat yourself on the back for a job well done!

If it's not working, I suggest reviewing Part 1 and  Part 2  of this tutorial.

Should you require additional form input fields, make sure to add them to:
  • HTML form, 
  • the list of defined variables in your PHP script,
  • PHP error messages,
  • don't forget to include them in the $body of your receiving email.   
Also remember that PHP code is cAsE sEnSiTiVe.  So please be consistent.  To avoid critical code errors, use all small case letters without any spaces or special characters in your form IDs, names and variables.  Underscores_ and hyphens- are permitted. 

I hope you have enjoyed this 3-part introductory tutorial on creating a responsive contact form with Bootstrap and PHP code.  If you are so inclined:
  • DONATE via my PayPal button (Help feed the kitty) to the right,
  • g+ this on Google  
Thank you!

Part 1 - Creating HTML5 doc type with Bootstrap Contact Form
Part 2 - Creating the PHP Script

Part 3 - Creating Error & Success Reporting in the Contact Form




Responsive Contact Form with Bootstrap 3.2 and PHP (Part 2)

If you stumbled on to this blog from a search engine, I highly recommend reading Part 1 of this tutorial.  It discusses Bootstrap and the necessary structure for our HTML5 Contact Form.

In this tutorial, we will create a PHP form processing script for our contact form.  As you'll remember from the previous tutorial, these are the form fields we have created so far:

name (required)
email (required)
phone (optional)
message (required)
human (required, math problem)

First, we will add this PHP code above our contact form's document type declaration or DTD.

<?php
// NOTE: this page must be saved as a .php file.
// And your server must support PHP 5.3+ and PHP Mail().
// Define variables and set to empty values
$result = $name = $email = $phone = $message = $human = "";
$errName = $errEmail = $errPhone = $errMessage = $errHuman = "";
    if (isset($_POST["submit"])) {
        $name = $_POST['name'];
        $email = $_POST['email'];
        $phone = $_POST['phone'];
        $message = $_POST['message'];
        $human = intval($_POST['human']);
}
//end form processing script
?>


Next, we will tell the script where the form data is coming from (an address on your web server)  and where it should be sent (your email address). Then we define which form fields should be included in the email you receive. Insert this code below the $human = intval($_POST['human']); code above.

        //valid address on your web server
        $from = 'webmaster@yourdomain.com';
        //your email address where you wish to receive mail
        $to = 'you@yourdomain.com';
        $subject = 'MESSAGE FROM YOUR WEB SITE';
        $headers = "From:$from\r\nReply-to:$email";
        $body = "From: $name\n E-Mail: $email\n Phone: $phone\n Message: $message";

}
//end form processing script
?>


Next, we need to validate our form fields to ensure they are not empty and create some error messages.  We want to ensure the email field is in a valid format so we will use the PHP email filter.  Then we will create a solution value for the simple math problem.  Spambots can't do math but humans can.  This will keep spambots from submitting your form.

// Check if name is entered
if (empty($_POST["name"])) {
$errName = "Please enter your name.";
} else {
    $name = test_input($_POST["name"]);
}
// Check if email is entered
if (empty($_POST["email"])) {
$errEmail = "Please enter your email address.";
} else {
    $email = test_input($_POST["email"]);
    // check if e-mail address is valid format
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      $errEmail = "Invalid email format.";
    }
}
// Check if phone is entered although it's not required so no error message is needed
if (empty($_POST["phone"])) {
$phone = "";
} else {
    $phone = test_input($_POST["phone"]);
}

//Check if message is entered
if (empty($_POST["message"])) {
$errMessage = "Please enter your message.";
} else {
    $message = test_input($_POST["message"]);
}

//Check if simple anti-bot test is entered
if (empty($_POST["human"])) {
$errHuman = "Please enter the sum.";
} else {
     if ($human !== 12) {
     $errHuman = 'Wrong answer. Please try again.';
        }
}
//end form processing script
?>


The next step is to test_input and sanitize it.  We don't want human hackers or robots injecting unwanted garbage or exploiting our forms so we trim white spaces,  strip slashes & html special characters and finally sanitize data with a PHP filter.  See here for more on PHP Sanitize Filters.

}
   //sanitize data inputs   
   function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   $data = (filter_var($data, FILTER_SANITIZE_STRING));
   return $data;
}
//end form processing script
?>


So what's left?  We need to give users some feedback.  Since we're using Bootstrap, we will rely on the ready-made Bootstrap Alert classes and Glyphicons for our form submission Success and Error messages.  We will insert this code just above the test_input sanitizing function above.

// If there are no errors, send the email & output results to the form
if (!$errName && !$errEmail && !$errPhone &&  !$errMessage && !$errHuman) {
    if (mail ($to, $subject, $body, $from)) {
        $result='<div class="alert alert-success"><h2><span class="glyphicon glyphicon-ok"></span> Message sent!</h2><h3>Thank you for contacting us. Someone will be in touch with you soon.</h3></div>';
    } else {
        $result='<div class="alert alert-danger"><h2><span class="glyphicon glyphicon-warning-sign"></span> Sorry there was a form processing error.</h2> <h3>Please try again later.</h3></div>';
       }
    }
}
   //sanitize data inputs   
   function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   $data = (filter_var($data, FILTER_SANITIZE_STRING));
   return $data;
}
//end form processing script
?>


OK. That's it for the PHP script. In Part 3 of this tutorial, we will go back to the HTML code and add Error and Success reporting to our contact form.

Part 1 - Creating HTML5 doc type with Bootstrap Contact Form
Part 2 - Creating the PHP Script
Part 3 - Creating Error & Success Reporting in the Contact Form

Responsive Contact Form with Bootstrap 3.2 and PHP (Part 1)

This is Part 1 of a 3 Part Tutorial.

Today I will show you how to create a responsive contact form with Bootstrap's font-end framework and secure PHP code. When we are finished, your working contact form will:
  • Conceal your email address from robot harvesters,
  • Self-validate required input fields with server-side code, 
  • Test for robot submissions, 
  • Sanitize input fields & thwart header injections, 
  • Give feedback to your users,
  • Finally, the PHP script will send form data to your email address.  
NOTE:  Your server must support PHP 5.3 or higher and the PHP Mail () function.  If unsure, check with your web hosting provider.

LIVE DEMO

Let's get started.

Bootstrap is a very popular responsive code framework.  If you're new to Bootstrap, there is excellent documentation for it online.
To begin our project, we need an HTML5 document with links to Bootstrap & jQuery files hosted on content distribution networks or CDNs. I'm using these because it saves you the drudgery of downloading and uploading scripts to your server. 

Basic HTML5 document with Bootstrap 3.2.0 (feel free to use the latest version if you wish).

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Bootstrap Form and PHP Script</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--Bootstrap-->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">

</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">


<!--Our form will go inside here...>


<!--end col--></div>
<!--end row--></div>
<!--end container--></div>
<!--Latest jQuery Core Library-->
<script src="http://code.jquery.com/jquery-latest.min.js">
</script>
<!--Bootstrap-->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>



Next we will add a centered column block and form with some labels and input fields, a textarea for comments and a human test or math problem to keep robots from sending us spam.  To style our form, we will use the built-in Bootstrap form classes.

Bootstrap Form Code:

<div class="col-md-8 center-block">

<h3>Responsive Contact Form</h3>
<p class="required small">* = Required fields</p>



<!--begin HTML Form-->
<form class="form-horizontal" role="form" method="post" action=" ">

<div class="form-group">
<label for="name" class="col-sm-3 control-label"><span class="required">*</span> Name:</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="name" name="name" placeholder="First & Last">
</div>
</div>

<div class="form-group">
<label for="email" class="col-sm-3 control-label"><span class="required">*</span> Email: </label>
<div class="col-sm-9">
<input type="email" class="form-control" id="email" name="email" placeholder="you@domain.com">
</div>
</div>

<div class="form-group">
<label for="phone" class="col-sm-3 control-label">Phone: </label>
<div class="col-sm-9">
<input type="tel" class="form-control" id="phone" name="phone" placeholder="(123) 456-7890">
</div>
</div>

<div class="form-group">
<label for="message" class="col-sm-3 control-label"><span class="required">*</span> Message:</label>
<div class="col-sm-9">
<textarea class="form-control" row="4" name="message" placeholder="Tell us your story?"></textarea>
</div>
</div>

<div class="form-group">
<label for="human" class="col-sm-3 control-label"><span class="required">*</span> Human Test:</label>
<div class="col-sm-4">
<h3 class="human">6 + 6 = ?</h3>
<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer">
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-3 col-sm-6 col-sm-offset-3">
<button type="submit" id="submit" name="submit" class="btn-lg btn-primary btn-block">SUBMIT</button>
</div>
</div>
<!--end Form--></form>
<!--end col block--></div>


So far, so good.  Here's what our responsive form looks like.
Not too bad but I think it could use some CSS to make the required fields stand out more.  Also we can center the form on desktops and shore up the human math problem with it's adjacent label.  Add this CSS to your document's <head> tag.

<style>
.required {color:red; font-weight:bold}
.center-block {float:none}
.human {margin: 0 0 0 12px}
</style>


To summarize our work so far, here is the entire HTML5 code:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Bootstrap Form and PHP Script</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--Bootstrap-->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">

<style>
.required {color:red; font-weight:bold}
.center-block {float:none}
.human {margin: 0 0 0 12px}
</style>



</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">

<div class="col-md-8 center-block">

<h3>Responsive Contact Form</h3>
<p class="required small">* = Required fields</p>

<!--begin HTML Form-->
<form class="form-horizontal" role="form" method="post" action=" ">

<div class="form-group">
<label for="name" class="col-sm-3 control-label"><span class="required">*</span> Name:</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="name" name="name" placeholder="First & Last">
</div>
</div>

<div class="form-group">
<label for="email" class="col-sm-3 control-label"><span class="required">*</span> Email: </label>
<div class="col-sm-9">
<input type="email" class="form-control" id="email" name="email" placeholder="you@domain.com">
</div>
</div>

<div class="form-group">
<label for="phone" class="col-sm-3 control-label">Phone: </label>
<div class="col-sm-9">
<input type="tel" class="form-control" id="phone" name="phone" placeholder="(123) 456-7890">
</div>
</div>

<div class="form-group">
<label for="message" class="col-sm-3 control-label"><span class="required">*</span> Message:</label>
<div class="col-sm-9">
<textarea class="form-control" row="4" name="message" placeholder="Tell us your story?"></textarea>
</div>
</div>

<div class="form-group">
<label for="human" class="col-sm-3 control-label"><span class="required">*</span> Human Test:</label>
<div class="col-sm-4">
<h3 class="human">6 + 6 = ?</h3>
<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer">
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-3 col-sm-6 col-sm-offset-3">
<button type="submit" id="submit" name="submit" class="btn-lg btn-primary btn-block">SUBMIT</button>
</div>
</div>
<!--end Form--></form>
<!--end col block--></div>


<!--end col--></div>
<!--end row--></div>
<!--end container--></div>
<!--Latest jQuery Core Library-->
<script src="http://code.jquery.com/jquery-latest.min.js">
</script>
<!--Bootstrap-->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>


And here is what our form looks like now.

In Part 2 of this tutorial, I will discuss the PHP code.  We will define variables, check for empty fields, create error messages and sanitize input data to keep malicious hackers from exploiting our form. 

In Part 3 of this tutorial, I will show you how to connect your form to the processing script and add server-side error reporting directly to your contact form.