skip to content

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:

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.

< JavaScript

User Comments

Most recent 20 of 21 comments:

Post your comment or question

28 January, 2020

Thanks a lot,
It's the best I found when searching to build a modal window !
Keep up the good job !

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?

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

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:

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.

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.

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.

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.

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.

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.

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

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.

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.

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.

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?

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.

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.

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!

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.

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.

top