Most read posts this month



Jan 30th 2009 × Fit Flops – not really a flop?

This is kind of off-topic, but I can barely contain my laughter. I am a natural sceptic so when my wife told me of shoes that ‘exercise’ you as you walk, I just slapped my forehead… Even so–I decided to check this out–we contacted my old friend Alex over at Shoe Envy and asked her what all the Fit Flops hype was all about (the marketing malarkey that women buy into and all that). To my surprise, she actually said they were ‘cool’ and did give you a workout as you walked.

Well, seeing as it’s winter, we decided to chance it and ordered the FitFlops Billow Boots for her… at £69.95, Shoe Envy are by far the cheapest online Fit-Flops retailer I could find, so it got our cash… And off she goes–all smiles–with Mikaela on a walkabout in the park… Saying how she ‘feels’ her muscles ‘puffing’.

3 hours later, she’s back home, complaining of a reasonably acute muscle ache, hinting over foot massages and whatnot! You’d think that if your shoes tire you needlessly and leave you worse for wear, you’d ditch them, wouldn’t you? I certainly wouldn’t go around pimping them to other gullible women… Not my wife! Anyway–if you want to exercise your loved one without telling her so, get her a pair of Fit Flops and smile knowingly :D


Jan 20th 2009 × getting fancy with AJAX: your first form submission and verification

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.