2

I'm pretty strong with PHP, but javascript is totally new to me.

I need to add various ajax functionality to my projects, for example for form validation etc.

I've done some searching, watched some tutorials, and come up with a basic working example as follows:

index.php:

<!DOCTYPE html>
<html lang="en">
<head>
<title>Ajax form test</title>
<style>
 form input, form textarea {
 display:block;
 margin:1em;
 }
 form label {
 display:inline;
 }
 form button {
 padding:1em;
 }
</style>
</head>
<body>
<h2>CONTACT FORM</h2>
<div id="form_content">
 <form method="post" action="server.php" class="ajax">
 <label for="name" value="name">name:</label>
 <input type="text" name="name" placeholder="name" />
 <label for="email" value="email">email:</label>
 <input type="email" name="email" placeholder="email" />
 <label for="message" value="message">message:</label>
 <textarea name="message" placeholder="message"></textarea>
 <input type="submit" value="send">
 </form>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="main.js"></script>
</body>
</html>

main.js:

$('form.ajax').on('submit', function() {
console.log('trigger');
var that = $(this),
 url = that.attr('action'),
 type = that.attr('method'),
 data = {};
 that.find('[name]').each(function(index, value) {
 var that = $(this),
 name = that.attr('name'),
 value = that.val();
 data[name] = value;
 });
$.ajax ({
 url: url,
 type: type,
 data: data,
 success: function(response) {
 console.log(response);
 $('#form_content').load('server.php', data);
 }
});
return false;
});

and finally, server.php:

<?php
if (isset($_POST) AND $_POST['name'] !='' AND $_POST['email'] !='' AND $_POST['message'] !='')
{
?>
<h4>Your data was submitted as follows</h4>
<br />name: <?=$_POST['name']?>
<br />email: <?=$_POST['email']?>
<br />message: <?=$_POST['message']?>
<?php
} else {
?>
<h3>please fill in all form data correctly:</h3>
<form method="post" action="server.php" class="ajax">
 <label for="name" value="name">name:</label>
 <input type="text" name="name" placeholder="name" />
 <label for="email" value="email">email:</label>
 <input type="email" name="email" placeholder="email" />
 <label for="message" value="message">message:</label>
 <textarea name="message" placeholder="message"></textarea>
 <input type="submit" value="send">
</form>
<?php
}

This all works fine, in that if I enter all form data and click submit, the ajax magic happens and I get a confirmation of the data. Also if not all data is loaded, the form is re-presented on the page. The problem is that in such a case, continuing to fill out the form data and then submit it loads the server.php page instead of repeating the ajax call until the form data is valid..

I'm sure there's a better way to do this as it's my first attempt, but I haven't been able to find any solution by searching either here or on google, but that's probably mostly because I don't really know what to search for. how can I make the behaviour in the first instance repeatable until the form is submitted correctly ?

asked Sep 13, 2013 at 16:54
9
  • 4
    First time I see a strong PHP developer new to JavaScript Commented Sep 13, 2013 at 16:57
  • I'm sure it's not common, but it's true, and I'm still stuck on this :) and I did say pretty strong, relatively speaking. Commented Sep 13, 2013 at 16:59
  • @DontVoteMeDown Wish I could... does the phrase ad hominem mean anything to you? You speak --> Commented Sep 13, 2013 at 17:00
  • I would use your JS to see if any values are empty and IF so, don't send the AJAX request. Commented Sep 13, 2013 at 17:00
  • 1
    I was just joking. Nothing wrong with that. Commented Sep 13, 2013 at 19:17

2 Answers 2

3

This happens because you are removing your form element during your load() call and overwrite it with a new version of the form. Therefore all attached event handlers will vanish along with it.

You will need to use a delegate on an element that does not change:

$('#form_content').on('submit', 'form.ajax', function() {...});

Explanation:

In the above example, you attach the event listener to the #form_content element. However, it only listens to events that bubble up from the form.ajax submit event. Now, if you replace the form with a new version, the existing handler is attached higher up in the chain (on an element that doesn't get replaced) and continues to listen to events from lower elements, no matter if they change or not... therefore it will continue to work.

answered Sep 13, 2013 at 17:01
Sign up to request clarification or add additional context in comments.

1 Comment

thanks steve. I did wonder if it was something to do with replacing the form, but I don't know enough about JS and jQuery to have seen the details of the problem. Anyway it seems to be working now, thanks very much!
0

Your primary problem is that you are validating the form on the PHP side, when you should really validate it on the client side - THEN, instead of returning an appropriate response and continuing processing on the client side, you are finishing processing on the PHP side. Steve's answer (above) applies to what you are seeing.

As to the approach you have taken, it might be better to not use a <form> construction at all, because with AJAX you often don't need to. In my opinion, <form> is an archaic structure, not often needed in the age of AJAX. Notice how you had to add return false following the AJAX block to abort the default form functionality -- to stop it from sending the user over to server.php? That should tell you something.

Here is another way to structure it:

HTML:

<body>
<h2>CONTACT FORM</h2>
<div id="form_content">
 <label for="name" value="name">name:</label>
 <input type="text" name="name" placeholder="name" />
 <label for="email" value="email">email:</label>
 <input type="email" name="email" placeholder="email" />
 <label for="message" value="message">message:</label>
 <textarea name="message" placeholder="message"></textarea>
 <input type="button" id="mybutt" value="send">
</div>
<div id="responseDiv"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="main.js"></script>
</body>

JAVASCRIPT/JQUERY:

$(document).ready(function() {
 //Next line's construction only necessary if button is injected HTML
 //$(document).on('click', '#mybutt', function() {
 //Otherwise, use this one:
 $('#mybutt').click(function() {
 console.log('trigger');
 var valid = "yes";
 var that = $(this),
 url = "server.php",
 type = "POST",
 data = {};
 that.find('[name]').each(function(index, value) {
 var that = $(this),
 name = that.attr('name'),
 value = that.val();
 if (value=="") valid = "no";
 data[name] = value;
 });
 if (valid == "yes") {
 $.ajax ({
 url: url,
 type: type,
 data: data,
 success: function(response) {
 console.log(response);
 $('#responseDiv').html(response);
 /* OPTIONALLY, depending on what you make the PHP side echo out, something like:
 if (response == "allgood") {
 window.location.href = "http://www.google.com";
 }else{
 //this is how you would handle server-side validation
 alert('Please complete all fields');
 }
 */
 }
 }); //END AJAX
 }else{
 alert('Please complete all fields');
 }
 }); //END button.click
}); //END document.ready

PHP Side: server.php

<?php
 if (isset($_POST) AND $_POST['name'] !='' AND $_POST['email'] !='' AND $_POST['message'] !='') {
 $r = '';
 $r .= "<h4>Your data was submitted as follows</h4>";
 $r .= "<br />name: " . $_POST['name'];
 $r .= "<br />name: " . $_POST['email'];
 $r .= "<br />name: " . $_POST['message'];
 } else {
 $r = "Please complete all form fields";
 }
 echo $r;
answered Sep 13, 2013 at 17:44

5 Comments

"<form> is now an archaic structure, not much needed in the age of AJAX." - I couldn't disagree more. form has a semantic purpose and is still very important for accessibility. the fact that you are using AJAX has nothing to do with using form or not. They still work well together. It's a great wrapper for any form data, and truthfully gives you great ways to access form fields through JS. Most importantly it is the right tool for progressive enhancement of a page, because it gives you fallback possibilities for free.
Thanks Steve, good points. +1 I do tend to be too evangelistic about AJAX superseding FORMS which, as you correctly point out, is not universally true. However, for a long time <form>s were the only way to pass along data and, in my experience, AJAX beginners often stumble because they do not grasp how AJAX can be used apart from FORMs. A time and a place for each one, but only sometimes for both. IMO, this was a situation where using forms made the task more complicated than necessary. I updated my answer to address your valid and constructive critique.
sorry but I agree with steve and I already mentioned some of my reasons in response to Rottingham's comment above. I am using ajax to provide 'progressive enhancement' as steve said, to streamline the form entry process for the end user where that functionality is available. Where that is not available (for whatever reason), the form falls back gracefully to the normal PHP solution (or it will once I clean things up), and that is very important.
I take your point on forms being used with ajax when it's not necessary, and there will certainly be situations where I only need to change snippets of page data base on some condition, in which case I wouldn't use a form anyway. In this case, it's a simplified version but I will be using what I've learnt here to implement a more complex order form which previously required 2-3 page loads without the help of ajax.
As for validating in the client - I disagree with that and it would seem inefficient in this case, as I'd still have to do some validation and cleaning on the server side anyway, and it's possible for the validation code in JS to be altered which could cause unexpected results. Not to mention that I don't have enough knowledge of JS to do that at this point anyway.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.