AutoSave Form Fields using jQuery – .change(), focusout() and the deferred .when() functions

I have been prototyping some general approaches, some new functionality, and other various concepts, all part of how a larger system will work. After seeing some interesting and nostalgic things being done with jQuery, it gave me an idea for an approach that may be suitable to achieve some delayed asynchronous actions. Thanks to Aaron Powell for those neat walk-throughs.

My Idea is probably even simpler but focussed more around having elements of a form “submit themselves” in a way making use of new features of jQuery 1.5. I have not yet completed the polished version of this functionality, where it will handle errors and other complexities to be a robust solution. I do believe this approach does align with the progressive enhancement objectives of good websites, if a clients browser does not support this functionality there is still a standard submission of the form data available. But none-the-less would like to share/document my approach and direction.

Basic Flow

  1. User types-in/modifies an input field.
  2. jQuery code detects this.
  3. Asynchronously sends this piece of data.
  4. Provide elegant feedback when this is complete.

Improved flow (a future exercise)

  • Step 2 above, should count down and reset counting if that same field is changed before the data is sent. Still a “to do” item.
  • Step 4 isn’t exactly elegant at the moment; a confirmation message or icon shows up, which is rather crude.

Demo

Again thanks to Aaron for reminding me of the awesome site: jsFiddle, I used it to speed up my jQuery experiments without relying on Visual Studio and running an MVC application to create and test the jQuery logic.

$(':input').change(function() {
    var c = $(this);
    $.when(
    c.focusout()).then(function() {
        $('#last-action').append(c.attr('name') + ' = ' + c.val() + '<br />');
    });
});

Here is the jsFiddle demo of this functionality, simply type in any of the input boxes, and tab away and see the results be “submitted”. Of course no submit code is firing yet, we’ll look at that now.

Let’s refactor a little to support some more important functionality to get ready to submit our form. The line in particular about just appending the data can be replaced with a function to handle submitting the form, and just for the demo it will also still output the data in the little debug div. This is where I make use of Aaron’s demonstration of the recursive setTimeout pattern.

$(':input').change(function() {
    var c = $(this);
    $.when(
    c.focusout()).then(function() {
        startCountDownAndSendData(c, 5) //delay by 5 seconds
    });
});

With this function, we’re going to supply the html element (c) and an integer (waitDuration) representing how many seconds to wait before “submitting”.

function startCountDownAndSendData(c, waitDuration) {
    function go(){
        if(waitDuration <= 0) //count down from a supplied duration value (in seconds)
        {
            $('#last-action').append(c.attr('name') + ' = ' + c.val() + '<br />');
            $('form#MyFormId').trigger('submit');
            return;
        }
        waitDuration--;
        setTimeout(go, 1000);
    }
    go();
}

You can see this refactoring in operation here, but it won’t submit anywhere, that’s what we will handle next time in a post about Asynchronous MVC controllers. So steps from 3 and 4 are still to demonstrate to you dear reader, stay tuned… part two is here.

REMIX 2010 – Melbourne – Share the Web Love

This week on Tuesday & Wednesday (1st & 2nd) of June. I’ll be attending REMIX 10. #auremix on Twitter. It’s being hosted at Crown.

remix 2010 melbourne

I haven’t finalised my session choices yet. I’ll update this post with what I attended. Along with some quick summaries of “Key Takeaways” as a Day 1 summary and a Day 2 summary.

I’ve setup a new Flickr account to upload photos I take. I’ll try and take a reasonable amount of shots. If by any chance you like any of the shots feel free to use them. Find it here: flickr.com/photos/confnick/.