JavaScript: A simple modal feedback form with no plugins
Almost every website these days has some kind of comment or feedback form. Often they rely on Facebook, Disqus or other third-party services, or require bloated libraries such as jQuery to function.
Here you can find instructions for setting up a very basic feedback form using just a few lines of CSS and JavaScript. The form will appear in a modal (popup) with the background greyed out.
Setting up the HTML
Below you will see code for a basic HTML form. The form is contained in a DIV identified as #modal_window which will be hidden by default when the page loads.
Above this, there is a button that will appear on the page, #modal_open, and the form is contained by #modal_wrapper (any other containing element can also be used).
<p><button id="modal_open">Open Email Form</button></p>
<div id="modal_wrapper">
<div id="modal_window">
<div style="text-align: right;"><a id="modal_close" href="#">close <b>X</b></a></div>
<p>Complete the form below to send an email:</p>
<form id="modal_feedback" method="POST" action="#" accept-charset="UTF-8">
<p><label>Your Name<strong>*</strong><br>
<input type="text" autofocus required size="48" name="name" value=""></label></p>
<p><label>Email Address<strong>*</strong><br>
<input type="email" required title="Please enter a valid email address" size="48" name="email" value=""></label></p>
<p><label>Subject<br>
<input type="text" size="48" name="subject" value=""></label></p>
<p><label>Enquiry<strong>*</strong><br>
<textarea required name="message" cols="48" rows="8"></textarea></label></p>
<p><input type="submit" name="feedbackForm" value="Send Message"></p>
</form>
</div> <!-- #modal_window -->
</div> <!-- #modal_wrapper -->
This is all pretty simple. What we want to achieve is for when 'Open Email Form' is clicked, an overlay appears over the website and the modal window is displayed at the centre of the screen.
People are asking how the form can be used to submit data to PHP or other server-side scripts. Just insert the target script as the action attribute of the HTML form above.
The autofocus attribute on the first input field works in Safari, Chrome and Opera in setting focus on that field when the modal window is displayed. It doesn't appear to work in Internet Explorer or Firefox.
The HTML5 required attribute is recognised in IE10 and higher, and many browsers will now display the associated title text as a tooltip if the field is left empty. We are still using standard JavaScript form validation (below) as a fallback.
Required CSS styles
We've used a minimum of CSS here, so the form is rather plain. Feel free to jazz it up yourself later. The CSS styles should be added to your existing style sheets or included in the document HEAD.
<style type="text/css">
#modal_wrapper.overlay::before {
content: " ";
width: 100%;
height: 100%;
position: fixed;
z-index: 100;
top: 0;
left: 0;
background: #000;
background: rgba(0,0,0,0.7);
}
#modal_window {
display: none;
z-index: 200;
position: fixed;
left: 50%;
top: 50%;
width: 360px;
overflow: auto;
padding: 10px 20px;
background: #fff;
border: 5px solid #999;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
}
#modal_wrapper.overlay #modal_window {
display: block;
}
</style>
In desktop browsers position: fixed will keep the popup centred on the screen as the page scrolls or the browser window is resized.
For this example we've set the width of the modal window to 360 pixels. This can be changed to suit your requirements. If you don't set either a width or max-width than any long segments of text will force the modal window wider.
Internet Explorer 8 does not support rgba colours. If you want a similar background to appear behind the modal window in IE8 you will need to apply the Microsoft proprietary filter effect for opacity. There are also some issues with the stacking order of ::before elements in IE8 which may require some tweaking if the background isn't visible.
JavaScript Form Validation
You should recognise the code here as a basic form validation script. It displays an alert message and prevents the form from being submitted if any of the mentioned fields are left blank.
<script type="text/javascript">
// Original JavaScript code by Chirp Internet: chirpinternet.eu
// Please acknowledge use of this code by including this header.
var checkForm = function(e)
{
var form = (e.target) ? e.target : e.srcElement;
if(form.name.value == "") {
alert("Please enter your Name");
form.name.focus();
e.preventDefault ? e.preventDefault() : e.returnValue = false;
return;
}
if(form.email.value == "") {
alert("Please enter a valid Email address");
form.email.focus();
e.preventDefault ? e.preventDefault() : e.returnValue = false;
return;
}
if(form.message.value == "") {
alert("Please enter your comment or question in the Message box");
form.message.focus();
e.preventDefault ? e.preventDefault() : e.returnValue = false;
return;
}
};
</script>
The checkForm function will be assigned to the form submit handler later in the code.
In modern browsers (apart from Safari) the validation task is performed by HTML5 and the JavaScript is redundant. Of course we still need server-side validation to prevent automated scripts from attacking the form handler.
Opening and closing the modal window
Now we come to the juicy part of the code. We want our modal window, containing the feedback form, to be displayed when the trigger is clicked, and to be hidden when any of a number of different events take place - when the 'close' link is clicked, the 'Esc' key is pressed, or when a mouse click occurs outside the modal window.
<script type="text/javascript">
// Original JavaScript code by Chirp Internet: chirpinternet.eu
// Please acknowledge use of this code by including this header.
var modal_init = function() {
var modalWrapper = document.getElementById("modal_wrapper");
var modalWindow = document.getElementById("modal_window");
var openModal = function(e)
{
modalWrapper.className = "overlay";
var overflow = modalWindow.offsetHeight - document.documentElement.clientHeight;
if(overflow > 0) {
modalWindow.style.maxHeight = (parseInt(window.getComputedStyle(modalWindow).height) - overflow) + "px";
}
modalWindow.style.marginTop = (-modalWindow.offsetHeight)/2 + "px";
modalWindow.style.marginLeft = (-modalWindow.offsetWidth)/2 + "px";
e.preventDefault ? e.preventDefault() : e.returnValue = false;
};
var closeModal = function(e)
{
modalWrapper.className = "";
e.preventDefault ? e.preventDefault() : e.returnValue = false;
};
var clickHandler = function(e) {
if(!e.target) e.target = e.srcElement;
if(e.target.tagName == "DIV") {
if(e.target.id != "modal_window") closeModal(e);
}
};
var keyHandler = function(e) {
if(e.keyCode == 27) closeModal(e);
};
if(document.addEventListener) {
document.getElementById("modal_open").addEventListener("click", openModal, false);
document.getElementById("modal_close").addEventListener("click", closeModal, false);
document.addEventListener("click", clickHandler, false);
document.addEventListener("keydown", keyHandler, false);
} else {
document.getElementById("modal_open").attachEvent("onclick", openModal);
document.getElementById("modal_close").attachEvent("onclick", closeModal);
document.attachEvent("onclick", clickHandler);
document.attachEvent("onkeydown", keyHandler);
}
};
</script>
The openModal function assigns a class 'overlay' to the wrapper DIV which triggers the CSS to display the overlay and modal window. It also centres the modal window to the screen using the calculated width and height.
To hide the modal window the closeModal function simply removes the 'overlay' class, hiding the extra elements. If the form is re-opened any information already entered will still be there.
The rest of the code is for tracking key presses to detect and 'Esc' (key code 27) or a click on the background.
To have the modal window/form open automatically on page load you can add a call to openModal() at the end of the initialisation function:
<script type="text/javascript">
// Original JavaScript code by Chirp Internet: chirpinternet.eu
// Please acknowledge use of this code by including this header.
var modal_init = function() {
...
openModal();
};
</script>
You cannot directly reference openModal from outside the initialisation script as it is only defined within the scope of that function.
Initialisation
The final step is to add an 'onload' handler to the page. This is used firstly to assign the form validation script to our form, and secondly to initialise the modal window code and events:
<script type="text/javascript">
if(document.addEventListener) {
document.getElementById("modal_feedback").addEventListener("submit", checkForm, false);
window.addEventListener("DOMContentLoaded", modal_init, false);
} else {
document.getElementById("modal_feedback").attachEvent("onsubmit", checkForm);
window.attachEvent("onload", modal_init);
}
</script>
Final Markup
The JavaScript code and CSS styles can of course be moved to external files. The CSS should be included in the HEAD and the JavaScript at the end of the BODY - as is standard:
<!DOCTYPE html>
<html>
<head>
<title>...</title>
...
<link rel="stylesheet" type="text/css" href="/feedback-modal-window.css">
</head>
<body>
... html code ...
<script type="text/javascript" src="/feedback-modal-window.js"></script>
</body>
</html>
Demonstration
Click the link below to see the modal window in action:
Complete the form below to send an email:
Our Feedback form below uses similar code, with the addition of a CAPTCHA and other enhancements. Use it to get in touch with us if you have any questions or comments.
Removing IE8 Support
You will see throughout the code some duplication when adding and working with event handlers. This is only required to support Internet Explorer 8. Removing IE8 can save some 25 lines of code from our already short script:
// Original JavaScript code by Chirp Internet: chirpinternet.eu
// Please acknowledge use of this code by including this header.
document.getElementById("modal_feedback").addEventListener("submit", function(e) {
var form = this;
if(form.name.value == "") {
alert("Please enter your Name");
form.name.focus();
e.preventDefault();
} else if(form.email.value == "") {
alert("Please enter a valid Email address");
form.email.focus();
e.preventDefault();
} else if(form.message.value == "") {
alert("Please enter your comment or question in the Message box");
form.message.focus();
e.preventDefault();
}
}, false);
window.addEventListener("DOMContentLoaded", function() {
var modalWrapper = document.getElementById("modal_wrapper");
var modalWindow = document.getElementById("modal_window");
var openModal = function(e)
{
modalWrapper.className = "overlay";
modalWindow.style.marginTop = (-modalWindow.offsetHeight)/2 + "px";
modalWindow.style.marginLeft = (-modalWindow.offsetWidth)/2 + "px";
e.preventDefault();
};
var closeModal = function(e)
{
modalWrapper.className = "";
e.preventDefault();
};
var clickHandler = function(e) {
if(e.target.tagName == "DIV") {
if(e.target.id != "modal_window") closeModal(e);
}
};
var keyHandler = function(e) {
if(e.keyCode == 27) closeModal(e);
};
document.getElementById("modal_open").addEventListener("click", openModal, false);
document.getElementById("modal_close").addEventListener("click", closeModal, false);
document.addEventListener("click", clickHandler, false);
document.addEventListener("keydown", keyHandler, false);
}, false);
On The Art of Web we load a polyfill for JavaScript events for IE8 so this shorter code will also work.
Related Articles - Form Validation
- HTML HTML5 Form Validation Examples
- HTML Validating a checkbox with HTML5
- JavaScript Preventing Double Form Submission
- JavaScript Counting words in a text area
- JavaScript Date and Time
- JavaScript Password Validation using regular expressions and HTML5
- JavaScript Tweaking the HTML5 Color Input
- JavaScript Form Validation
- JavaScript Credit Card numbers
- JavaScript Allowing the user to toggle password INPUT visibility
- JavaScript A simple modal feedback form with no plugins
- PHP Protecting forms using a CAPTCHA
- PHP Basic Form Handling in PHP
- PHP Measuring password strength
- PHP Creating a CAPTCHA with no Cookies
User Comments
Most recent 20 of 21 comments:
Post your comment or question
Philippe 28 January, 2020
Thanks a lot,
It's the best I found when searching to build a modal window !
Keep up the good job !
Martin Gitau 18 December, 2019
it is year 2019 and this modal proves very helpful. I have customized it to my website where i want to collect information to perform a query to my database using the input fields filled in and selected by my customers.
however it happens that i require more fields than the pop up can hold and now i want two or three more pop ups! the additional pop up are necessary only if i my customer wants to narrow down the search criteria, they may opt not to narrow down in which case i will just perform a query if they click a submit button.
how can i get a second and a third modal that may be positions itself on top of the existing modal and the user can dismiss it just like the way they can close the existing modal?
Robert 3 October, 2018
Thanks for the example. I added the files to my local server, but do not see the code to pass the info to my php script that can process the input.
Can you please show where this code is to go?
Just insert your target script as the action attribute of the HTML form
Kevin 7 September, 2018
Great little form - one thing I do not understand it how the data from the form is placed in an email and routed to the recipient.
But I do not see where/how this gets the form information into the email, or where to specify the destination of the email. Help! Thanks
This related article may help:
mdprps 5 August, 2017
madprops.github.io/Msg/ is a library that makes creating modal windows very simple. It has a lot of options and methods and it's fully customized through css to make any type of modal window.
Alex Ches 21 July, 2017
Thanks for a very useful piece of coding.
I have implemented it on a test web page where I need to use the modal window to display a jpg image but have 2 issues.
1. I need to re-size the modal window, (probably just a simple change in the css file but I can't find it).
2. I need to pass parameters to the modal window in order to open the correct image file and, possible, to dynamically change the window size, (aspect ratio etc).
Any suggestions would be welcome.
Thanks.
The 'width' CSS setting is highlighted in Section 2 above.
And for passing parameters you can add data-* attributes to the button and then reference them from the openModal() function using e.target.getAttribute() or e.target.dataset.
Sachin 10 November, 2016
Thank you for the tutorial, I liked it very much. But could you please explain that how you have implemented logic of tiny icon for notifications in this form.
You'll find that explained in this article.
Sri 4 August, 2016
Re. the last comment, if I have a bunch of divs for the modals with different content and I have to display the correct one when the appropriate link is clicked, how would I do it? Right now, I am adding eventListeners to the class "modal_open". However, only the the content of the first modal is displayed regardless of the link I click on.
Thanks
In our code setting class="overlay" on the wrapper causes CSS to display the modal window. If you have multiple windows you might try adding data-windowname="window1" to the link, and then setting the class to "overlay window1" with corresponding changes to the CSS.
James William 30 May, 2016
Hi,
Thanks for your sharing this popup form.
If i want to use this multiple times in same page then it is possible. can you provide this code..
Thanks
You can find instructions for having multiple buttons opening the same form in the comments below. It just involves using 'class' instead of 'id' to identify the button/s.
But if you mean opening different forms from different buttons, we've managed that by assigning data-* attribute values to the button and then referencing them from the openModal function.
Jason 23 May, 2016
If it doesn't stop JavaScript from executing dead in its tracks it's no different to a rectangle displayed to the screen.
I think the word MODAL should not just mean a rectangle on the screen with the background dimmed down, but an INTERRUPTION to JavaScript execution by a dialog box.
Robin Windon 20 May, 2016
Im trying to use this very awesome looking bit of code but im having a little problem hooking it up i have included all the code but when i click my button nothing happnes, im thinking i have put the onload event in the wrong place in the js file
Both already include the unload event
Yonatan 2 March, 2016
Thank you for the helpful post.
I have installed the code inside footer.php in a wordpress theme, because I wanted the modal to appear on any page the visitor is using as entrance page to the website.
Is there any way I can make the modal open up just one time per visit?
Yes, when it opens you set a cookie, and before it opens you first check for the presence of the cookie.
Wagaana Alex 13 January, 2016
Thank you a lot for this, Am right now working hard to make my website a dynamic site, and I will soon upgrade it with your code, thank you very much.
Amir 5 February, 2015
Thank for sharing!
The modal window is not acatuly behaving like a modal dialog. When modal division is displayed, user is still able to click out of the modal divition to parent document and click on the links.
Modal dialog must enforce the user to close the dialog before taking other action from the parent doucment!
Any idea to solve ths issue?
Regards, Amir
For our purposes we wanted users to be able to 'click away' the window and access the page. There are three (3) event listeners in the code that do that. One for the "Close" button, one for clicking outside the modal window, and one for detecting <Esc>.
Depending on what you want to achieve you could disable one or more of them.
Jason M 17 January, 2015
I am attempting to use your simple modal javascript, but i keep getting an error telling me that document is null and that because of that it can't read the property "addEventListener". How can I fix this?
Simone 16 January, 2015
Hi!
First thanks a lot for this wonderful contact form.
Besides one problem I have it works really well.
The modal opens and closes as required, if contact data is not completely a warning pops up etc.
But: when all asked data is inserted correctly the email will not be submitted to my email account. Can you please help me? Maybe my php code is wrong? Can you offer the php code for this contact form and where to insert it? Thank you a lot in advance!
What is the 'action' of your form? It needs to go to a (PHP) form handler/script that parses the $_POST variables and sends an email using the built-in mail() function (or PHPMailer or similar library).
The rest is up to your mail program.
Randy D 11 January, 2015
I have been using your modal-window code and find it very useful. Today, I attempted to add the openModal(); at the end of the initialization function, but it does not seem to load the modal window when the page loads. Do you have an example page where you have it implemented?
All you need is to add the line openModal(); as the very last line of the modal_init function and it should work. If not, send some code.
Jimmy S 15 November, 2014
Is there a way I can make this script autoload so the modal will be displayed on page load instead of by clicking the 'open email form' button?
Thank you so much - this script works great!
mike krueger 4 November, 2014
I am new to javascript and really like your simple modal feedback form with no plugins. I also followed the step by step but can not get it to load. Is there some where I can get the complete code
Thanks
You can find more or less the complete markup on the page in section 6, including links to the required CSS and JS files. Where it says "... html code ..." just insert the HTML from section 1.
Stooki Blakelock 20 September, 2014
Can you send me the full source with all css and js references. i tried duplicating step by step your example. However my Modal form wont load. Nothing happens at all. Your help is appreciated.