Check out my latest project: Full Frontal JavaScript Conference

jQuery AJAX'ed forms

Inspired by Dustin Diaz’s AJAX screencast, I thought it was time I made a little more use of iShowU and show how easy, and quick it can be to pile on some AJAX calories to pretty much any form.

The screencast is sans-sound, really just to try to keep my out-going bandwidth down, but I’ve commented along the way so you can understand (…hopefully…) what I’m doing, and why I’m doing it.

Download the QuickTime screencast, 9MB, a little over 10 minutes

If you can’t view the screencast, try DivX Web Player for Windows or the Mac.

You can also have a look the code used in the screencast to have a play or to upgrade.

As always, let me know if you have any questions or suggestions.

Watch out for this gotcha that I just stumbled in to: if your form has an input element with the name 'action', the line url: this.action is going to grab that element, rather than the form's action. Instead, use this.getAttribute('action')

64 Responses to “jQuery AJAX'ed forms”

  1. Wonderful. Many thankyou's for making this. This will be an invaluable demonstration of how to make an ajax form with jQuery. You'll find that these demo's are perhaps one of the best resources for people to learn from.

    One recommendation I'd have about your use of Firebug is to take advantage of the larger command line :). Although you may have just turned it off for the demo.

    Other than that, it's great to see another textmate user. Great screencast. Cheers.

  2. sorry lorry, works...
    but i had to remove the value: contact from the action

  3. Wicked awesome contact form. I am trying to modify it slightly for a project I am working on and don't need the message text input area. When I wipe it out and submit the form, the submission alert returns the source of the page. I thought that if the process failed I would get one of the error messages.

    I've got a sample of the form on my site at http://www.speakingdigital.com/subscribe/

    Thanks much,
    Steve

  4. Remy,

    My stupidity led me to ignore the second line in the file. When I pulled the message text area, I needed to change the:

     $_REQUEST['message']
    

    I've switched it to something else. I chose:

     $_REQUEST['email']
    

    One thing I did notice is that the form submits without an e-mail. I figured this should not happen with the above change made to the code. Any thoughts?

    Thanks again,
    Steve

  5. @Steve - I've had a look at the link your provided, and the front end looks all present and correct - i.e. all the values are being passed through in the AJAX request properly.

    If you're missing the value submitted on the server side, I would be inclined to do a bit of debugging - start with:

    var_dump($_REQUEST)

    Just to get an idea of what you're actually capturing.

    Let me know how you get on.

  6. Remy,

    Can you do me a favor and drop me a line at [email hidden]. It seems as if something in your blog is stripping out code in the posts. Are you on any IM's?

    Thanks much,
    Steve

  7. I got a better way to do that:

    html file :

    Pagina Index

     <div id="contact">
      <form id="contact_form" method="post" action="javascript:procesareForm();">
      <fieldset title="Contact">
        <table>
          <tr>
            <td>
            Nume:
            </td>
            <td>
            <input type="text" name="nume" />
            </td>
           </tr>
           <tr>
            <td>
             Email:
            </td>
            <td>
            <input type="text" name="email" />
            </td>
            </tr>
            <tr>
            <td>
             Subiect:
            </td>
            <td>
            <input type="text" name="subiect" />
            </td>
            </tr>
            <tr>
            <td>
             Mesaj:
            </td>
            <td>
           <textarea rows="8" cols="50" name="mesaj"></textarea>
            </td>
            </tr>
            <tr>
            <td>
             Newsletter:
            </td>
            <td>
              <input type="checkbox" name="newsletter" />
            </td>
          </tr>
          <tr>
           <td colspan="2">
            <input type="submit" name="trimite" value="trimite" />
           </td>
          </tr>
        </table>
        </fieldset>
      </form>
    
     </div>
    

    code js :
    function procesareForm()
    {
    var parametri1 = $("input").serialize();
    var parametri2 = $("textarea").serialize();
    var parametri = parametri1 '&' parametri2;

    $.ajax({
    type: "POST",
    url: "php/trimitemesaj.php",
    data: parametri,
    success: function(msg){
    $('#contact').attr('innerHTML','Mesajul has been send ' msg);
    }
    });

    }

    preloader.js ...made by me ...maybe a plug in..

    //Pt centrarea preloader ului
    var Page = new Object();
    Page.width;
    Page.height;
    Page.top;
    Page.getPageCenterX = function ()
    {
    var fWidth;
    var fHeight;
    //For old IE browsers
    if(document.all)
    {
    fWidth = document.body.clientWidth;
    fHeight = document.body.clientHeight;
    }
    //For DOM1 browsers
    else if(document.getElementById &&!document.all)
    {
    fWidth = innerWidth;
    fHeight = innerHeight;
    }
    else if(document.getElementById)
    {
    fWidth = innerWidth;
    fHeight = innerHeight;
    }
    //For Opera
    else if (is.op)
    {
    fWidth = innerWidth;
    fHeight = innerHeight;
    }
    //For old Netscape
    else if (document.layers)
    {
    fWidth = window.innerWidth;
    fHeight = window.innerHeight;
    }
    Page.width = fWidth;
    Page.height = fHeight;
    Page.top = window.document.body.scrollTop;
    }
    jQuery().ajaxStart(showPreloader);
    jQuery().ajaxStop(hidePreloader);

    function showPreloader(){
    Page.getPageCenterX();
    $('#loading').show();
    $('#loading').css('top' ,(Page.top Page.height/2)-100);
    $('#loading').css('left',Page.width/2-75);
    $('#loading').css('position','absolute');
    }
    function hidePreloader(){
    $('#loading').hide();
    }

    trimitemesaj.php - which insert the message in the database it not send email:
    $value) $$key = $value;
    if ($newsletter=='on') $newsletter = 1; else $newsletter = 0;

    $sql = "INSERT INTO mesaje
    (nume,email,subiect,mesaj,newsletter)
    VALUES
    ('$nume','$email','$subiect','$mesaj','$newsletter')";
    $result = $conexiune->query($sql);

    if ($result)
    {
    echo 'success';
    }
    else
    {
    echo 'invalid';
    }
    ?>

  8. @Gafitescu - thanks for the huge comment ;-)

    I can't particularly see how it's a better implementation, aside from the overlay saying it's being posted and when it's complete.

    In particular, the code only handles a finite number of form inputs, i.e. if you add anymore inputs, you need to change your JavaScript. The code I offered allows us to dynamically collect all the inputs on the page:

    $(':input', this).each(function() {
    inputs.push(this.name '=' escape(this.value));
    })

    Finally, and most importantly, your code isn't accessible. You've set the action attribute of the form to the JavaScript. If JavaScript it turned off (the stats say somewhere between 8-15% of users) then the entire form fails and you don't have your newsletter subscription.

    I hope that feedback all makes sense. Cheers.

  9. $(”input”).serialize(); - you can add as many inputs and textarea as you like...I am serialize the object diffrent...

    I didn't know that so many users disable js....but I know how to modify it in order to run with disabled js

    Tutorials that you wrote are great..,very inspiring..I write the preloader....can be extended to a plug in?

  10. Please. I need your help. I was working with funtion $.post(...);
    But my php-script use $_REQUEST. When I put $_POST my parameters dont exist. Why??.

    I want to use $_POST How can i get it???

  11. @Harold, it's a simple change, which should make the variables available in $_POST. The change is in the JavaScript, within the jQuery.ajax() call. I've made the change you need in bold below:

    jQuery.ajax({
      data: inputs.join('&'),
      type: "POST",
      url: this.action,
      timeout: 2000,
      error: function() {
      console.log("Failed to submit");
      },
      success: function(r) {
        alert(r);
      }
    });

  12. Hi Remy,

    Thanks for the very informative screencast.

    The typed comments were great :-)

    Mei

  13. Sweet, great demo. This is actually the beste ajax tutorial I have ever seen.

  14. Remy, that rocked.

    Thanks,
    Eamo.

  15. The $(":input") trick looks very nice, but it seems it has a drawback:

    Every checkbox in the form, checked or not, will be collected in this way, while on a normal submitted form only the checked checkboxes are submitted. See the difference? Catastrophic when processing data on the serverside.

    So if you are using checkboxes (and perhaps some other elements like radiobuttons) in your form, stay away from :input. There is a Selectors Plugin for jquery that gives a bit more control. http://www.softwareunity.com/sandbox/JQueryMoreSelectors/

  16. Great tutorial, Remy! Thanks! I'm a noob, and this really helped me out.

  17. Hi!
    Nice tutorial. Seems I'm the only one that can't get additional fields to work. I tried to add some radio buttons. But they are not automatically collected. Sorry for being such a moron. :)

    Fyll i i fälten nedan
    Platform:
    Mac
    Pc
    Linux
    Annan

            <label for="email">E-postadress:</label> <input type="text" name="email" value="" id="email" /><br />
            <label for="name">Namn:</label> <input type="text" name="name" value="" id="name" /><br />
            <label for="message">Meddelande:</label>
            <textarea name="message"></textarea>
            <p><input type="submit" value="Skicka" /></p>
          </fieldset>
        </form>
    
  18. Great script and excellent ScreenCast!

    I've got one question for you though. I'm using a form where the widely used TinyMCE is working it's magic on my text-area. When it does so, jQuery can't see what has been written in the textfield.

    Do you know how to get this working? :)

    Sincerely,
    Magnus

  19. @Magnus - I use TinyMCE for a few of my projects, so I might be able to answer. If you run the following code, it commits what's in TinyMCE to the textarea:

    tinyMCE.triggerSave();

    I would probably make that the first thing that happens when the submit method is called.

  20. So what happens when IE overrides and actually runs the Submit?

    What I mean is - my form is running an external php file:

    So IE navigates to the php file on Submit. Why am I not surprised...

    FF and Safari don't though. Is there a way stop IE from running the Submit?

Leave a Reply
Not required

CODE: Please escape code and wrap in <pre><code>, doing so will automatically syntax highlight