Sick Gaming
[Tut] Bootstrap Contact Form with JavaScript Validation and PHP - Printable Version

+- Sick Gaming (https://www.sickgaming.net)
+-- Forum: Programming (https://www.sickgaming.net/forum-76.html)
+--- Forum: PHP Development (https://www.sickgaming.net/forum-82.html)
+--- Thread: [Tut] Bootstrap Contact Form with JavaScript Validation and PHP (/thread-99031.html)



[Tut] Bootstrap Contact Form with JavaScript Validation and PHP - xSicKxBot - 03-21-2022

Bootstrap Contact Form with JavaScript Validation and PHP

<div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/09/bootstrap-contact-form-with-javascript-validation-and-php.jpg" width="300" height="374" title="" alt="" /></div><div><p>Last modified on September 7th, 2020.</p>
<p>Bootstrap is the most popular solution to design an optimum, intuitive, mobile-ready UI components. It is easy to integrate the Bootstrap library for the application interface.</p>
<p>Often, many of my readers ask for a Bootstrap contact form code. So I thought of creating a basic example for a Bootstrap enabled PHP contact form.</p>
<p>Bootstrap provides in-built features to take care of UI responsiveness, form validation, and more. I used its SVG icon library to display the contact form fields with suitable icons.</p>
<p>A Bootstrap contact form looks enriched. UI attracts people and enables them to use it with ease. Also, the developers’ effort is reduced by using the Bootstrap framework.</p>
<p>I have created a <a href="https://phppot.com/shop/contact-form-iris/">secure feature-packed responsive contact form – Iris</a>. This is one of the best and sleek contact form component you can ever get.</p>
<h2>What is inside?</h2>
<ol>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#contact-form-with-vs-without-bootstrap">Contact form with vs without Bootstrap</a></li>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#majority-of-the-contact-form-fields">Majority of&nbsp; the contact form fields</a></li>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#about-this-example">About this example</a></li>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#file-structure">File Structure</a></li>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#slim-ui-components-with-the-bootstrap-contact-from">Slim UI layout with the Bootstrap contact from</a></li>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#contact-form-validation-with-plain-javascript">Contact form validation with plain JavaScript</a></li>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#processing-contact-form-data-in-php-code">Processing contact form data in PHP code</a></li>
<li><a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#bootstrap-contact-form-ui-output">Bootstrap contact form UI output</a></li>
</ol>
<p>A contact form collects a different type of user details like name, message and more. There are various popular templates for contact forms.</p>
<p>I have created various <a href="https://phppot.com/php/php-contact-form/">PHP contact form</a> examples. And those form templates uses my own custom CSS.</p>
<p>Though it is straight forward to go with custom CSS, designing with <a href="https://getbootstrap.com/">Bootstrap</a> gives irrefutable offer.</p>
<p>Bootstrap provides full-fledged styles to create various types of form layout. It includes more of element-specific, attribute-specific forms styles.</p>
<p>With a Bootstrap contact form, the responsiveness, the cross-browser compatibilities are an easy deal.</p>
<p>If you already use the Bootstrap framework, then also it would be natural not to choose the custom CSS UI option.</p>
<p>For a simple example to prepend icons to form inputs without Bootstrap needs a bunch of CSS and media queries. But, with Bootstrap it has <em>input-group</em> selector to achieve this.</p>
<p>In case if you want to render a thin, primitive contact form, then custom CSS is preferable.</p>
<p>Most of the contact forms have the name, email, subject, message fields. Some times it varies based on the applications’ purpose.</p>
<p>For example, site-admin may merge the user feedbacks and inquiries entry points. In such cases, the contact form may have a radio option group to choose between feedback and inquiry.</p>
<p>Sometimes, people may collect phone numbers with country code. Also, it may have <a href="https://phppot.com/php/how-to-get-the-client-user-ip-address-in-php/">checkbox options to receive GDPR consent</a> as per the European legislation.</p>
<p>In a way, contact forms become complex in positioning fields, giving fluidity and more aspects.</p>
<p>Bootstrap supports a variety of layout options to create even a more complex form. Based on the complexity of the contact form layout, the Bootstrap is even dependable.</p>
<h2 id="about-this-example">About this example</h2>
<p>This example uses rebooted form styles with classes to create a Bootstrap contact form. It makes this form UI responsive and consistent in all browsers and viewports.</p>
<p>It includes a default contact form having vertically stacked form controls. Each form-control has a prepended icon suitable to the contact input. I downloaded the Bootstrap SVG icon library to have such icons.</p>
<p>The form validation with a plain JavaScript simplifies the effort of loading any external libraries.</p>
<p>In PHP, it handles the posted data for sending them via a contact email. Also, it stores the data into a database table if any. It is optional and can disable in code.</p>
<p>This code uses a simple <a href="https://www.php.net/manual/en/function.mail.php">PHP mail() function</a> for sending the emails. In a previous example, I have added <a href="https://phppot.com/php/send-email-in-php-using-gmail-smtp/">how to send email using Gmail SMTP.</a> Replace the simple mail() function with the one using PhpMailer via Gmail SMTP.</p>
<h2 id="file-structure">File Structure</h2>
<p>The contact form code is a small integrative component of an application. This example contains a very minimal code of having a Bootstrap contact form.</p>
<p>The vendor directory includes the Bootstrap CSS and icon library.</p>
<p>The <em>bootstrap-contact-form.php</em>file contains the contact form HTML template. The landing page renders the contact form by including this template.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-12015" src="https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-file-structure.jpg" alt="Bootstrap Contact Form File Structure" width="300" height="374" srcset="https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-file-structure.jpg 300w, https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-file-structure-241x300.jpg 241w" sizes="(max-width: 300px) 100vw, 300px"></p>
<p>This section shows the Bootstrap contact form HTML code. This HTML shows a default vertically stacked contact form fields.</p>
<p>The Bootstrap form grid styles and CSS provides options to display a horizontal form.</p>
<p>In the below HTML, each form element is in a <em>form-group</em> container. It groups the form element label, form controls, validation and help-text properly.</p>
<p>The Email field has a help text that displays a note spaced as <em>text-muted</em>.</p>
<p>The <em>input-group </em>specific styles help to display icon-prepended form controls. These icons are from the Bootstrap SVG icon library.</p>
<p class="code-heading">bootstrap-contact-form.php</p>
<pre class="prettyprint lang-php">&lt;html&gt;
&lt;head&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"&gt;
&lt;title&gt;Bootstrap Contact Form&lt;/title&gt;
&lt;link rel="stylesheet" href="./vendor/bootstrap/css/bootstrap.min.css"&gt;
&lt;/head&gt;
&lt;body class="bg-light"&gt; &lt;div class="container"&gt; &lt;div class="row py-4"&gt; &lt;div class="col"&gt; &lt;h2&gt;Bootstrap Contact Form&lt;/h2&gt; &lt;/div&gt; &lt;/div&gt; &lt;form name="frmContact" id="frmContact" method="post" action="" enctype="multipart/form-data" novalidate&gt; &lt;div class="row"&gt; &lt;div class="form-group col-md-4"&gt; &lt;label&gt;Name&lt;/label&gt; &lt;span id="userName-info" class="invalid-feedback"&gt;&lt;/span&gt; &lt;div class="input-group"&gt; &lt;div class="input-group-prepend"&gt; &lt;span class="input-group-text"&gt;&lt;?php require __DIR__ . '/vendor/bootstrap/bootstrap-icons/person.svg';?&gt;&lt;/span&gt; &lt;/div&gt; &lt;input type="text" class="form-control" name="userName" id="userName" required&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="form-group col-md-4"&gt; &lt;label&gt;Email&lt;/label&gt; &lt;span id="userEmail-info" class="invalid-feedback"&gt;&lt;/span&gt; &lt;div class="input-group"&gt; &lt;div class="input-group-prepend"&gt; &lt;span class="input-group-text"&gt;&lt;?php require __DIR__ . '/vendor/bootstrap/bootstrap-icons/envelope.svg';?&gt;&lt;/span&gt; &lt;/div&gt; &lt;input type="email" name="userEmail" id="userEmail" class="form-control" required&gt; &lt;/div&gt; &lt;small id="emailHelp" class="form-text text-muted"&gt;Your email will not be shared.&lt;/small&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="form-group col-md-8"&gt; &lt;label&gt;Subject&lt;/label&gt; &lt;span id="subject-info" class="invalid-feedback"&gt;&lt;/span&gt; &lt;div class="input-group"&gt; &lt;div class="input-group-prepend"&gt; &lt;span class="input-group-text"&gt;&lt;?php require __DIR__ . '/vendor/bootstrap/bootstrap-icons/question.svg';?&gt;&lt;/span&gt; &lt;/div&gt; &lt;input type="text" name="subject" id="subject" class="form-control" required&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="form-group col-md-8"&gt; &lt;label&gt;Message&lt;/label&gt; &lt;span id="content-info" class=" invalid-feedback"&gt;&lt;/span&gt; &lt;div class="input-group"&gt; &lt;div class="input-group-prepend"&gt; &lt;span class="input-group-text"&gt;&lt;?php require __DIR__ . '/vendor/bootstrap/bootstrap-icons/pencil.svg';?&gt;&lt;/span&gt; &lt;/div&gt; &lt;textarea class="form-control" rows="5" name="message" id="message" required&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="col"&gt; &lt;input type="submit" name="send" class="btn btn-primary" value="Send Message" /&gt; &lt;/div&gt; &lt;/div&gt;
&lt;?php
if (! empty($displayMessage)) { ?&gt; &lt;div class="row"&gt; &lt;div class="col-md-8"&gt; &lt;div id="statusMessage" class="alert alert-success mt-3" role="alert"&gt;&lt;?php echo $displayMessage; ?&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;
&lt;?php
}
?&gt; &lt;/form&gt; &lt;/div&gt; &lt;script type="text/javascript" src="./js/validation.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt; </pre>
<p>The above HTML template imports the Bootstrap CSS from the vendor location.</p>
<p>After submitting the contact details, users will receive an acknowledgment message. The bootstrap <em>success</em> alert box displays a positive response on successful mail sending.</p>
<p>All the fields are mandatory in this Bootstrap contact form example.</p>
<p>The <em>js/validation.js</em> file has the validation script. On the window load event, this script sets the submit event listener to check the form validity.</p>
<p>Once it found invalid form fields, it will prevent the form to submit. Added to that it will add Bootstrap custom validation styles to highlight the invalid fields.</p>
<p>It adds the <em>.was-validated</em> class to the parent form element. It highlights the form fields with respect to the<span>&nbsp;<em>:valid</em> and&nbsp;</span><em>:invalid</em><span> pseudo-classes.</span></p>
<p>Apart from the red-bordered invalid field highlighting, the script displays a text-based error message. The <em>setValidationResponse()</em> checks the form data and insert the error message into the target.</p>
<p>This custom function invokes <em>markAsValid()</em> and&nbsp;<em>markAsInvalid()</em> to show the error messages. These functions set the element’s display property and the innerText.</p>
<p class="code-heading">js/validation.js</p>
<pre class="prettyprint lang-php">(function() { 'use strict'; window.addEventListener('load', function() { var form = document.getElementById('frmContact'); form.addEventListener('submit', function(event) { if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); setValidationResponse(); } form.classList.add('was-validated'); }, false); }, false);
})(); function setValidationResponse() { var emailRegex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; var userName = document.getElementById("userName").value; var userEmail = document.getElementById("userEmail").value; var subject = document.getElementById("subject").value; var content = document.getElementById("message").value; if (userName == "") { markAsInvalid("userName", "required"); } else { markAsValid("userName"); } if (userEmail == "") { markAsInvalid("userEmail", "required"); } else if(!emailRegex.test(userEmail)) { markAsInvalid("userEmail", "invalid"); } else { markAsValid("userEmail"); } if (subject == "") { markAsInvalid("subject", "required"); } else { markAsValid("subject"); } if (content == "") { markAsInvalid("content", "required"); } else { markAsValid("content"); }
} function markAsValid(id) { document.getElementById(id+"-info").style.display = "none";
} function markAsInvalid(id, feedback) { document.getElementById(id+"-info").style.display = "inline"; document.getElementById(id+"-info").innerText = feedback;
}
</pre>
<p>This section is something common in all of my contact forms example. But, this is important for which we have started.</p>
<p>In this example, it has support to store the contact form data into a database. But, it is optional and configurable in the coding.</p>
<p>The PHP code has a variable&nbsp;<em>$isDatabase</em> which may have a boolean <em>true</em> to enable the database.</p>
<p class="code-heading">structure.sql</p>
<pre class="prettyprint">--
-- Database: `bootstrap_contact_form`
-- -- -------------------------------------------------------- --
-- Table structure for table `tbl_contact`
-- CREATE TABLE `tbl_contact` ( `id` int(11) NOT NULL, `user_name` varchar(255) NOT NULL, `user_email` varchar(255) NOT NULL, `subject` varchar(255) NOT NULL, `message` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1; --
-- Indexes for dumped tables
-- --
-- Indexes for table `tbl_contact`
--
ALTER TABLE `tbl_contact` ADD PRIMARY KEY (`id`); --
-- AUTO_INCREMENT for dumped tables
-- --
-- AUTO_INCREMENT for table `tbl_contact`
--
ALTER TABLE `tbl_contact` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
</pre>
<p>The below code shows the backend logic created in PHP for handling the posted data. This code has the default PHP<em> mail()</em> function to send the contact details.</p>
<p class="code-heading">index.php</p>
<pre class="prettyprint lang-php">&lt;?php
use Phppot\DataSource; if (! empty($_POST["send"])) { $name = $_POST["userName"]; $email = $_POST["userEmail"]; $subject = $_POST["subject"]; $message = $_POST["message"]; $isDatabase = false; if ($isDatabase) { require_once __DIR__ . "/lib/DataSource.php"; $ds = new DataSource(); $query = "INSERT INTO tbl_contact (user_name, user_email, subject, message) VALUES (?, ?, ?, ?)"; $paramType = "ssss"; $paramArray = array( $name, $email, $subject, $message ); $ds-&gt;insert($query, $paramType, $paramArray); } $toEmail = "[email protected]"; $mailHeaders = 'From: [email protected]' . "\r\n" . 'Reply-To: ' . $name . '&lt;' . $email . "&gt;\r\n" . 'X-Mailer: PHP/' . phpversion(); $mailHeaders = "From: " . $name . "&lt;" . $email . "&gt;\r\n"; // if lines are larger than 70 chars, then should be wrapped $message = wordwrap($message, 70, "\r\n"); // your PHP setup should have configuration to send mail $isValidMail = mail($toEmail, $subject, $message, $mailHeaders); if ($isValidMail) { $displayMessage = "Message sent. Thank you."; }
}
require_once __DIR__ . "/bootstrap-contact-form.php"; </pre>
<p>After setting <em>$isDatabase</em> to true, configure the database details in this class to connect the database for the contact form action.</p>
<p class="code-heading">lib/DataSource.php</p>
<pre class="prettyprint lang-php">&lt;?php
/** * Copyright © Phppot * * Distributed under 'The MIT License (MIT)' * In essense, you can do commercial use, modify, distribute and private use. * Though not mandatory, you are requested to attribute Phppot URL in your code or website. */
namespace Phppot; /** * Generic datasource class for handling DB operations. * Uses MySqli and PreparedStatements. * * @version 2.6 - recordCount function added */
class DataSource
{ const HOST = 'localhost'; const USERNAME = 'root'; const PASSWORD = 'test'; const DATABASENAME = 'bootstrap_contact_form'; private $conn; /** * PHP implicitly takes care of cleanup for default connection types. * So no need to worry about closing the connection. * * Singletons not required in PHP as there is no * concept of shared memory. * Every object lives only for a request. * * Keeping things simple and that works! */ function __construct() { $this-&gt;conn = $this-&gt;getConnection(); } /** * If connection object is needed use this method and get access to it. * Otherwise, use the below methods for insert / update / etc. * * @return \mysqli */ public function getConnection() { $conn = new \mysqli(self::HOST, self::USERNAME, self::PASSWORD, self::DATABASENAME); if (mysqli_connect_errno()) { trigger_error("Problem with connecting to database."); } $conn-&gt;set_charset("utf8"); return $conn; } /** * To get database results * * @param string $query * @param string $paramType * @param array $paramArray * @return array */ public function select($query, $paramType = "", $paramArray = array()) { $stmt = $this-&gt;conn-&gt;prepare($query); if (! empty($paramType) &amp;&amp; ! empty($paramArray)) { $this-&gt;bindQueryParams($stmt, $paramType, $paramArray); } $stmt-&gt;execute(); $result = $stmt-&gt;get_result(); if ($result-&gt;num_rows &gt; 0) { while ($row = $result-&gt;fetch_assoc()) { $resultset[] = $row; } } if (! empty($resultset)) { return $resultset; } } /** * To insert * * @param string $query * @param string $paramType * @param array $paramArray * @return int */ public function insert($query, $paramType, $paramArray) { $stmt = $this-&gt;conn-&gt;prepare($query); $this-&gt;bindQueryParams($stmt, $paramType, $paramArray); $stmt-&gt;execute(); $insertId = $stmt-&gt;insert_id; return $insertId; } /** * To execute query * * @param string $query * @param string $paramType * @param array $paramArray */ public function execute($query, $paramType = "", $paramArray = array()) { $stmt = $this-&gt;conn-&gt;prepare($query); if (! empty($paramType) &amp;&amp; ! empty($paramArray)) { $this-&gt;bindQueryParams($stmt, $paramType, $paramArray); } $stmt-&gt;execute(); } /** * 1. * Prepares parameter binding * 2. Bind prameters to the sql statement * * @param string $stmt * @param string $paramType * @param array $paramArray */ public function bindQueryParams($stmt, $paramType, $paramArray = array()) { $paramValueReference[] = &amp; $paramType; for ($i = 0; $i &lt; count($paramArray); $i ++) { $paramValueReference[] = &amp; $paramArray[$i]; } call_user_func_array(array( $stmt, 'bind_param' ), $paramValueReference); } /** * To get database results * * @param string $query * @param string $paramType * @param array $paramArray * @return array */ public function getRecordCount($query, $paramType = "", $paramArray = array()) { $stmt = $this-&gt;conn-&gt;prepare($query); if (! empty($paramType) &amp;&amp; ! empty($paramArray)) { $this-&gt;bindQueryParams($stmt, $paramType, $paramArray); } $stmt-&gt;execute(); $stmt-&gt;store_result(); $recordCount = $stmt-&gt;num_rows; return $recordCount; }
} </pre>
<p>This screenshot shows the Bootstrap contact form example output. It displays the valid fields in green and the invalid fields in red.</p>
<p>This indication will notify the user on clicking the “Send Email” submit button.</p>
<p><img loading="lazy" class="alignnone size-large wp-image-12011" src="https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-output-550x381.jpg" alt="Bootstrap Contact Form Output" width="550" height="381" srcset="https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-output-550x381.jpg 550w, https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-output-300x208.jpg 300w, https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-output-768x532.jpg 768w, https://phppot.com/wp-content/uploads/2020/08/bootstrap-contact-form-output.jpg 1200w" sizes="(max-width: 550px) 100vw, 550px"></p>
<p>On successful mail sending, a success response will send to the user as shown below.</p>
<p><img loading="lazy" class="alignnone size-large wp-image-12013" src="https://phppot.com/wp-content/uploads/2020/08/contact-form-success-response-550x49.jpg" alt="Contact Form Success Response" width="550" height="49" srcset="https://phppot.com/wp-content/uploads/2020/08/contact-form-success-response-550x49.jpg 550w, https://phppot.com/wp-content/uploads/2020/08/contact-form-success-response-300x27.jpg 300w, https://phppot.com/wp-content/uploads/2020/08/contact-form-success-response.jpg 600w" sizes="(max-width: 550px) 100vw, 550px"><br /><a class="download" href="https://phppot.com/downloads/bootstrap-contact-form.zip">Download</a></p>
<p> <!-- #comments --> </p>
<div class="related-articles">
<h2>Popular Articles</h2>
</p></div>
<p> <a href="https://phppot.com/php/bootstrap-contact-form-with-javascript-validation-and-php/#top" class="top">↑ Back to Top</a> </p>
</div>


https://www.sickgaming.net/blog/2020/08/29/bootstrap-contact-form-with-javascript-validation-and-php/