Having frequented the Digital Point Forums as of recent, I have come to the conclusion that most people are barely coping with the concepts of javascript and AJAX. So much so that they are struggling to interpret anything that is more advanced than changing a few field names and including some javascript files in the page header.
Naturally – people wanting it to ‘just work’ are right, of course. There will be plenty of solutions out there for most things that can do this and achieve it in such a way that does not warrant an understanding of any javascript concept. But there comes a day when you go ‘hold on, what if I need to do this?’ and find you are stuck with a solution that you cannot comprehend…
I guess all my posts thus far have been aimed at a different type of person – one that is more ‘at home’ with javascript and mootools. Time to go back to basics…
*edit* if you’ve come here for the magical email regex that will cover _any_ RFC compliant email, here it is:
var validEmailRegex = /^(([^<>()[\]\\.,;:\s@\”]+(\.[^<>()[\]\\.,;:\s@\”]+)*)|(\”.+\”))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
click here to view sample tests and code
The most common use for AJAX that seems to draw the crowds is still a form submission. It can be via GET or via POST, it may do some form processing for required fields and so forth. But it needs to submit without a page reload and it needs to output something back. So, how do you set about creating an AJAX form?
1. First of all, grab a copy of a javascript framework. A framework is simply a library of pre-set functions and methods you can use in your own pages. I tend to use mootools but anything will do – read my post on selecting a framework. In this example, we WILL use mootools, however.
2. Create your form page. As basic as this example is, we need to assume at you have at the very least the rudimentary skill of being able to compose a form in HTML. What you should try to do is to get your form working and submitting data to your PHP or ASP or CGI processor page on its own – and we will then convert your page into an AJAX submission instead. Here is an example form page:
<div id="feedback" style="background: #eee; padding: 2px; border: 1px solid #333; float: left"> <form action="mooForm.php?a=send" method="POST" id="myform"> <label for="customer_name">Your name:</label><p> <input type="text" class="required bordered" value="" name="customer_name" id="customer_name"/><p> <label for="customer_email">Your email:</label><p> <input type="text" class="required bordered" value="" name="customer_email" id="customer_email"/><p> <label for="customer_comment">Your message:</label><br /> <textarea class="required" style="width: 360px" name="customer_comment" id="customer_email"/></textarea><br /><br /> <input type="submit" value="Send data" /></form> </div>
3. Create a wrapper element for the form where we will output the reply: when contact_us.php is ‘reached’ and the data is saved, it can send us feedback to this effect – something along the lines of: “Thank you for your submission”. To do so, just add <div id=”feedback”> … </div> around your form – or you can keep it to the side, up to you and your styling preferences. We are going to be ‘replacing’ the form with the reply, however. Here it is how it all looks and works ‘on-screen’:
4. Attach javascript to intercept the form submission: you need to take control of what happens once the user presses “Send data”. Do this by fetching a copy of mootools and uploading it to your server. Within the head section of your site, you’d add the following:
<script type="text/javascript" src="mootools-1.2.1core.js"></script> <script type="text/javascript"> // in mootools, the 'onload' event is called 'domready' and it ensures // the DOM has completed loading and elements can be modified safely. window.addEvent("domready", function() { // now, add events for the form $("myform").addEvents({ "submit": function(e) { // stop the event from propagation... e.preventDefault(); new Request({ url: this.get("action"), data: this, onComplete: function() { $("feedback").set("html", this.response.text); } }).send(); } }); }); // end domready </script>
Although, you can leave it at that, to get a working AJAX form
5. Expand on your code to add some error checking. Of course, you can use PHP or ASP or whatever serverside language you like to inspect the data being submitted – and probably should do so anyway. But it helps if you can add some trapping clientside as well – on the off-chance it reduces errors and keeps your server load lower.
// extend elements to support warnings within values Element.implement({ fieldWarning: function(warningText, warningDelay) { // very basic - changes the value of the input to warningText // restores to "" within warningDelay in ms this.set({ value: warningText, styles: { backgroundColor: "#fcc" }, events: { focus: function() { this.set({ value: "", styles: { backgroundColor: "#fff" } }).removeEvents(); } } }); (function() { this.fireEvent("focus").removeEvents(); }).delay(warningDelay, this); } }); var validEmailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // define common functions and variables var isValid = function(email) { // boolean function that checks email string against allowed strings in accordance to RFCs return email.test(validEmailRegex); }, // end isValid cleanData = function(elementsArray) { // cleans passed elements with property 'value' from spaces and XSS elementsArray.each(function(el) { el.set("value", el.get("value").clean().stripScripts()); }); // end each } // end cleanData window.addEvent("domready", function() { // now, add events for the form $("myform").addEvents({ "submit": function(e) { // stop the event's default action from propagation... e.preventDefault(); // can also do new Event(e).stop(); // clean all form fields from excess spaces and cross side scripting attacks cleanData($("myform").getElements("input,textarea")); var noErrors = true; // first, loop required elements $$("input.required,textarea.required").each(function(el) { var testedValue = el.get("value"); if (testedValue.length == 0 || testedValue == "Required field") { noErrors = false; el.fieldWarning("Required field", 2000); } }); if (noErrors) { // test email var testedEmail = $("customer_email").get("value"); if (!isValid(testedEmail)) { $("customer_email").fieldWarning("INVALID: " + testedEmail, 2000); noErrors = false; } } // if no errors in the form, compose the XHTTP request manually. if (noErrors) new Request({ url: this.get("action"), data: this, onComplete: function() { $("feedback").set("html", this.response.text); // since the form itself is contained within this layer // it will 'self destroy' with whatever HTML we print // from the PHP/ASP. } }).send(); } }); });
What is taking place here? For the purposes of this small form, we are going to perform 2 types of javascript validations: a required field (which they all are) – a check to see if the length of the strings entered is greater than zero; and an email verification test – a check to see if the email string is compliant with RFCs, done via a regex test.
You can download the javascript above by clicking here and look at it at your own leisure.
If I keep reading your posts at DP and here I’m eventually going to have to learn mootools. It looks cool anyway.
heh! there’s no shame in learning mootools, its easy and powerful 🙂 i hope i can help convert at least a few people anyway
certainly nyjil_kk–apologies, I accidentally deleted your comment :(.
mooForm.php is not much of a file – in this example, all it really does is to output whatever POST data has arrived.
In the real world, it should also verify the data and write it out to a DB or email.
I will zip it up when I get back from work. To be honest, I have never tried to package and release anything I code as I look at it as snippets 🙂
No worries mate… 🙂
It would be great if you can help me with some stuff… I am not good at JS… I saw a “Blog Roll” at http://css-tricks.com/examples/BetterBlogroll.zip … but that’s done in JQuery… it would be great if you can do it in mooTools… 😀
I love nooTools for some reason… 😛
By the way… thank you somuch for your previous reply and the code… 😀 Greatly appreciated brother… 🙂
erm – so basically, a system for horizontal content scroll with a possible tabs system…
I am currently writing something similar to contain my ‘recent posts’ in mootools which has most of the functionality this blogroll does. It’s going to be a matter of some simple changes to do something like http://nettuts.s3.amazonaws.com/036_BetterBlogRoll/sourceFiles/index.html#1 – in fact, this is rather elementary.
here it is, the basic functionality of the scroller–all it needs is the data, skin /css and wordpress integration. http://fragged.org/dev/tabbed_blogroll.php