Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm having one, admittedly very minor issue with a contact form I've set up in WordPress using jQuery, jQuery form and PHP Mail to send a form-generated email.

To replace my current contact form which performs a pHp validation from within the contact form page and then sends using PHP Mail, I've designed the following simple html 5 form (which can be seen on this page: http://edge.donaldjenkins.net/contact):

<form id="contact" method="post" action="">
<fieldset>  

    <label for="name">Name</label>
    <input type="text" name="name" placeholder="Your Name" title="Enter your name" class="required">

    <label for="email">E-mail</label>
    <input type="email" name="email" placeholder="[email protected]" title="Enter your e-mail address" class="required email">

    <label for="phone">Phone</label>
    <input type="tel" name="phone" placeholder="ex. (555) 555-5555">

    <label for="website">Website</label>
    <input type="url" name="url" placeholder="http://">

    <label for="message">Question/Message</label>
    <textarea name="message"></textarea>

    <label for="checking" class="hidden">If you want to submit this form, do not enter anything in this field</label><input type="text" name="checking" class="hidden">

    <input type="submit" name="submit" class="button" id="submit" value="Send Message" />

</fieldset>

I then use the jQuery validate [jquery.validate.js] and form [jquery.form.js] plugins to perform a client-end validation:

<script src="js/jquery.validate.js"></script>
<script src="js/jquery.form.js"></script>

<script>
$(function(){
$('#contact').validate({
submitHandler: function(form) {
    $(form).ajaxSubmit({
    url: 'send-message.php',
    success: function() {
    $('#contact').hide();
    $('#instructions').hide();
    $('#status').show();
    $('#popular-posts').show();
    $('#status').append("<p>Thanks! Your request has been sent.  One will try to get back to you as soon as possible.</p>")
    }
    });
    }
});         
});
</script>

After the validation, the above script uses jQuery.form's ajaxSubmit function to submit the date to a server PHP page, send-message.php (the reason being that javascript can't send email). I use this PHP file to carry out a second, server-side validation of the data (though this is probably redundant, since because the setup relies on javascript to pass the data on to the server, one can safely assume that no one will be able to use the form without javascript enabled). It also performs a honeypot captcha check on data in a hidden input field added in the form. The email is then sent:

<?php 
//invoke wp_load in order to use WordPress wp_mail plugin function instead of mail for    better authentification of the sent email
require_once("/path/to/wp-load.php");

//Check to see if the honeypot captcha field was filled in
if(trim($_POST['checking']) !== '') {
$captchaError = true;
$errors .= "\n Error: Captcha field filled in";
} else {

//Check to make sure that the name field is not empty
if(trim($_POST['name']) === '') {
    $errors .= "\n Error: Name field empty";
    $hasError = true;
} else {
    $name = strip_tags($_POST['name']);
}

//Check to make sure sure that a valid email address is submitted
if(trim($_POST['email']) === '')  {
    $emailError = 'You forgot to enter your email address.';
    $hasError = true;
} else if (!eregi("^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}$", trim($_POST['email']))) {
    $errors .= "\n Error: Message field empty";
    $hasError = true;
} else {
    $email = strip_tags($_POST['email']);
}

//Check to make sure comments were entered  
if(trim($_POST['message']) === '') {
    $errors .= "\n Error: Message field empty";
    $hasError = true;
} else {
    $phone = strip_tags($_POST['phone']);
    $url = strip_tags($_POST['url']);
    if(function_exists('stripslashes')) {
        $message = stripslashes(trim($_POST['message']));
    } else {
        $message = strip_tags($_POST['message']);
    }
}
//If there is no error, send the email
if(!isset($hasError)) {

    // Send Message 
    $emailTo = '[email protected]';
    $subject = 'Contact Form Submission from '.$name;
    $body = "Name: $name \n\nEmail: $email \n\nPhone: $phone \n\nWebsite: $url \n\nMessage: $message";
    $headers = 'From: My Site <'.$emailTo.'>' . "\r\n" . 'Reply-To: ' . $email;

    wp_mail($emailTo, $subject, $body, $headers);

    $alert = 'Thanks! Your request has been sent.  One will try to get back to you as soon as possible.';
} else {
    $alert = $errors;
}
} ?>

The server keeps track of whether errors were found or whether the email was successfully sent in variable $alert.

After the pHp function completes, the script hides the form from the contact page and displays a previously hidden html element to which it appends an alert message.

The issue I can't solve is making javascript change the wording of that alert message to reflect whether the email was or not successfully sent, because I don't know how to pass the requisite pHp variable ($alert) containing a list of the error messages in the server PHP process to the script for insertion in the Contact Form page. Of course, again, this is a very theoretical concern, since for the reasons stated above, it's unlikely that an error-prone message would even have reached the PHP stage in the first place.

I've tried inserting the following code at the end of the PHP file, to no avail:

<script type="text/javascript">
alert = <?php echo $alert; ?>;
</script>

The latter attempt doesn't generate any errors in Firebug, but the variable value doesn't get passed on. Any ideas or thoughts welcome.

UPDATE: I added this workflow chart to clarify the setup for this issue: enter image description here

share|improve this question
It should work. Look at the generated page; what is the contents of the script at the bottom? And don't forget quote marks. – Lightness Races in Orbit Mar 12 '11 at 17:01
@Tomalak: Thanks! I tried (1) adding the quotes to the above script on the pPh process page, and then (2) changed the appropriate line in the script on the contact form page to $('#status').append(alert). It generates no errors in the Firebug console, but the text of the original pHp $alert doesn't get pasted in the html element. See this screenshot for the empty element on the form, despite Firebug saying the variable has been passed on: cl.ly/5BPx. – Donald Jenkins Mar 12 '11 at 17:12
1  
When I send a submission with no message text, I don't even get validation errors: the submission succeeds. You need to narrow down this problem quite significantly as I suspect that you have a few. – Lightness Races in Orbit Mar 12 '11 at 17:17
1  
@Donald: Where does alert come from in that code? Where are you passing it from, and how? I think I get it now. You have to parse the results of the AJAX request to retrieve the alert from within it. I suggest that the send-message.php return JSON. – Lightness Races in Orbit Mar 12 '11 at 18:29
1  
You should probably be aware that ereg, eregi and friends have been deprecated in modern PHP versions. You should probably stop using them. Also, your email regex is overly restrictive and you should consider a more comprehensive drop-in solution.. – Charles Mar 12 '11 at 20:45
show 16 more comments

2 Answers

up vote 1 down vote accepted

In send-message.php, put the alert text in an IDd <div />:

<div id="statusmsg" style="display: none">
<?php echo $alert ?>
</div>

Then your Javascript on the calling page ought to look like this:

<script type="text/javascript">
$(function() {
    $('#contact').validate({
        submitHandler: function(form) {
            $(form).ajaxSubmit({
                url: 'send-message.php',
                success: function(data) {

                    $('#contact').hide();
                    $('#instructions').hide();
                    $('#status').show();
                    $('#popular-posts').show();

                    // Make DOM object from result
                    var $DOMObj = $(data);

                    // Retrieve status message, if any
                    var $status = $('#statusmsg', $DOMObj);

                    // Show status message, if any
                    if ($status) {
                          $status
                                 .css('display', '')
                                 .appendTo('#status');
                    }
            }
            });
        }
    });         
});
</script>

Hopefully you can see how I've used a parameter to the success callback to retrieve the HTML contents of the AJAX request response, located the statusmsg div and appended it to the relevant element on the calling page.

More optimally, send-message.php would print JSON rather than HTML, making this process a little easier. I'll leave that as an exercise for the reader.. at least in this question thread.

share|improve this answer
Wow: impressive, thanks a lot. What happens, though, is that the variable now clearly makes it into the calling page (see console output at bottom of screenshot: cl.ly/5Cus). But you'll also see from that screenshot that the #statusmsg html element hasn't been appended. I can't work out why, as the script says to append to #status. – Donald Jenkins Mar 13 '11 at 8:03
I looked into using JSON, and found this: <script type="text/javascript"> var o = <?php echo json_encode($alert); ?>; alert(o.name); </script> but it doesn't seem to work either. – Donald Jenkins Mar 13 '11 at 8:09
@Donald: That script tag has nothing at all to do with passing JSON as the request response. Let's just focus on HTML for now. You need to debug the script I posted above using Firebug. Step through it line by line, watching the contents of each variable, and of $('#status'). Also I forgot that you'll need to remove the display: none CSS (now updated); you should still see the text in your Firebug console appended to $status even though it wasn't visible in the browser. – Lightness Races in Orbit Mar 13 '11 at 14:17
I've been mobilised getting the new site in production, but it's now online, so I'll resume betatesting for the contact form on the sandbox site this evening. Getting that site off the ground was a lot of work! Now this contact form passing back of data issue is the only one I've still not resolved… Back soon with more results and thanks again. – Donald Jenkins Mar 15 '11 at 12:35

You want to return the success or failure of the email in response to the AJAX call.

For this sample example, you could simply return false or true. If you needed more information, return a JSON string such as...

{
   "success": true,
   "something": ["something", "something-else"]
}

You can easily turn an array into JSON in PHP with json_encode().

share|improve this answer
Thanks for that. Of course, I don't just want to return whether the email was successfully sent or not. I also need to pass on the error messages that the pHp process has stored in the $alert variable. That's what I'm not able to pass on to the script (remember, the pHp and the script are on different pages). – Donald Jenkins Mar 12 '11 at 16:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.