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')

66 Responses to “jQuery AJAX’ed forms”

  1. Really good tutorial. Could you tell me what HTML editor you are using?

  2. @Mark – TextMate – possibly the best development tool I’ve had the pleasure to work with :-)

  3. @Remy – Thanks, i will check that out. I like the shortcuts and textcomplete that i seen in the screencast.

    Also, could you recommend any good forums for php devleopers. For chatting and jquery help.

    Edit – Arggh, its for mac, unfortunately i use windows.

    Edit – Found E-TextEditor for Windows that works with TextMate Bundles. Will give it a go now. I’m so sick of dreamweaver for text editing.

  4. tnx 4 sharing this code

    I am using asp and I was able to integrate this code to Classic ASP and .Net in no time.

    keep more jQuery ajax stuff coming plz

    PS. your comment count down is COOL :)

    -Norik

  5. Hi Remy,
    As a bloody beginner with Jquery I really appreciate your screencasts and writeups. I am familiar with prototype (somewhat), but this jquery breaks my neck. I am playing with your code from ajaxed forms and added the fix from Greg Hartwig for the check and select boxes…ALL worked nicely until I added a multi select box, and this box is only posted with 1 value. I tried .serialize which sends Everything, but also refreshes the page and does not really process it.
    So I am stumped, any help is greatly appreciated, thanks

  6. Hi Remy,

    I trying to add a comment system in a knowledge base. Now typically, I can add a form at the end of an article which the user can fill and submit it. The data is sent to the db and the URL refreshes sending the user back to the add a comment page. The posted comment is now appearing above the add a comment box, like in a blogging system.

    Now I want to use ajax or any other option to accomplish the same without the URL refresh. An example could be this location:

    http://typo.i24.cc/logahead/?2006/09/26/your_comments

    The fields I am trying to capture is comment_id (int 10, primary key, auto increment), article_id (int 10, hidden field), comment_author (varchar, captured using a hidden field and username value), comment_description (text), comment_date(datetime).

  7. Hey Remy, thanks for this work!

    What would you recommend if my form id was not static but dynamic? In my case the id is output by a php script and so it is impossible to “hard code” the javascript for each possible form id. How could I make this dynamic to handle different ids?

    Thanks

  8. Hi Remy,

    Your code continues to be a great help to me, but I’ve stumbled onto what I think is a small weakness. I notice that if people use the + symbol in their text, it gets removed. I think this might come from this line:

    $(':text', this).each(function() {
    myFieldsAry.push(this.name + '=' + escape(this.value));
    })

    Maybe there is something I can do to “this.value” prior to escaping it?

  9. Remy,

    Looking back I see that the $(':text', this).each part is a modification that I made myself. Do you still have an example of the code in action somewhere on your site though? I’d like to see if the plus (+) signs get ripped out of your solution also. I can’t figure out what to do.

  10. K, I solved all my problems all by myself. First, using “:input” to yank all the data from the form didnt cut it for me because it doesnt read checkboxs, radio buttons, or select boxes correctly. Also, just using “escape(this.value)” didn’t work, because it stripped the “+” signs out. Below is how I reconfigured that part of your script:

    $(':text', this).each(function() {
      var temptext = escape(this.value);
      temptext = temptext.replace("+", "%2B");
      //myFieldsAry.push(this.name + '=' + escape(this.value));
      myFieldsAry.push(this.name + '=' + temptext);
    })
    $(':option-sel', this).each(function() {
      var mySelName = escape(this.value);
      var myTempSelAry = mySelName.split("_");
      // alert(myTempSelAry[0] + '=' + myTempSelAry[1]);
      myFieldsAry.push(myTempSelAry[0] + '=' + myTempSelAry[1]);
    })
    $(':hidden', this).each(function() {
      myFieldsAry.push(this.name + '=' + escape(this.value));
    })
    $(':file', this).each(function() {
      myFieldsAry.push(this.name + '=' + escape(this.value));
    })
    var myFields = myFieldsAry.join('&');

    Later I ran into a new problem, which is that your script is using GET! But we’re letting users write stuff! Some of them write a whole lot, which leads to the “414 Request-URI Too Large” error. After panicking for about an hour, I realized it was very easily remedied with a single parameter in your ajax line:

    jQuery.ajax({
      // data: inputs.join('&'),
      type: "POST",
      data: myFields,
      url: this.action,
      timeout: 45000,
      error: function() {
        console.log("Failed to submit - ");
      },
      success: function(r) {
        $('.content').html(r);
      }
    })

    Now everything is working great! I think you should consider making these permanent changes to your code, as I find that they are huge, but easily implemented, improvements.

  11. @Todd – that’s not quite right.

    First up, :input does select all the input elements, but if you only want the selected elements, then this may not be for you.

    Second, escape isn’t what you want – you want uriEncodeComponent – this will handle the + symbols.

    Lastly, the Ajax hit that includes this.action is wrong, as it will put the input with the id of ‘action’ from the form, rather than the attribute.

    I suspect most of these issues have been caused by my own original demo, but you can see a working demonstration of all the points I’ve raised here:

    http://jsbin.com/uholo (to edit: http://jsbin.com/uholo/edit)

    I should add that the data attribute of the $.ajax function, you probably just want:

    jQuery.ajax({
      type: "post",
      data: $(this).serialize(), // assuming this == the form
      url: $(this).attr('action'),
      // ...etc - rest of fields
    });
  12. Remy,
    First the JS Bin is awesome. You are the man!

    Second, I’d never seen uriEncodeComponent before. Thanks for that bit.

    Third, this.action is working perfect for me so far – and I use all kinds of different action urls. Can you elaborate on when it will bust? I notice in my code i use this.action (normal ole jscript) and you refer to $(‘this’).attr(‘action’) which is JQuery code. I’ve been using this.action to grab the form action url for a long time. I’m inclined to believe you are right but then theres the “if it ain’t broke, don’t fix it” rule which even overrules advice from superior coders. Heh.

    Thanks for your help, brother!

  13. i need to get the id (?=136) from 1 page (review_image.php) and sent it to another (submitComment.php), then from there upload the database. please help me im new to this. and bin googleing for weeks now.

  14. Hey Remy,

    Just getting into jquery and Ajax and ma having issues submitting a form. I used your code and it submitted great but it refreshed the screen and redirected the user. how do I keep that from happening? I have tried other code which submits fine with out refresh but for some reason it takes all the spaces out of the text being submitted.

  15. thanks for adaptation of Dustin Diaz’s screencast! and for providing a link to original page.
    it’s amazing.
    just right what i want to see about jQuery + AJAX.

    some tweaks and discuss in the comments are helpful too.

    good luck!