How to use AJAX to submit forms without pressing a submit button

Posted on 12th September 2017

Summary
In addition to the speed benefits that come from automatically saving form fields, it makes for a nice user experience and can sometimes avoid disasters!

Introduction

Forms are such a chore aren't they?! In particular having to press that pesky submit button whenever you make a change is soooo tiresome! Well fear not - because AJAX has come to rescue you! Or rather - AJAX has been here to rescue you since 2005... But no matter, because you can still use this technique with your forms that you create... today!

Is it more involed? Well there's a smidgen more to it - and it'll probably take a little while to get used to it - making your forms this way. But once you have it will come as second nature.

An example form

Here's an example form that you can update to your hearts content. It sends the information that you give it off to the server where it's saved in the session. It's not used by anything - and with your own forms you'd send the information off to a server-side script that saves it to a database so that it can be used productively!





The HTML code

This is the HTML code that you use in your page. It includes a smidgen of PHP that takes the default values for the form fields out of the session. If you were using a database - you could get them out of that instead.

<input type="text" name="autosave-forms-name" value="<?php echo htmlspecialchars($_SESSION['autosave-forms-name']) ?>" placeholder="Enter your name" onkeyup="saveformdata()" id="name" /><br />
<input type="text" name="autosave-forms-age" value="<?php echo htmlspecialchars($_SESSION['autosave-forms-age']) ?>" placeholder="Enter your age" onkeyup="saveformdata()" id="age" /><br />
<input type="text" name="autosave-forms-location" value="<?php echo htmlspecialchars($_SESSION['autosave-forms-location']) ?>" placeholder="Enter your location" onkeyup="saveformdata()" id="location" /><br />

The JavaScript code

Here's the JavaScript code that saves the form data as you enter it by sending it with AJAX to your server. There's a simplified standalone example page linked to below where you can see this in action.

<script>
    // Create the TIMERS object
    TIMERS = {};

    //
    // Save the information from the form by sending it to the server via an
    // AJAX GET request. If you have a lot of data you could use POST here
    // instead
    //
    function saveformdata()
    {
        // Get the form information and put it in the opt variable
        var opt = {
            name: document.getElementById('name').value,
            age: document.getElementById('age').value,
            location: document.getElementById('location').value
        };

        // If there's already a timer - cancel it (we're about to create a
        // new one). This means that we don't register many new timers
        if (TIMERS.SAVEDATA) {
            clearTimeout(TIMERS.SAVEDATA);
        }

        // Create the new timer - which runs after a delay of a second
        TIMERS.SAVEDATA = setTimeout(function ()
        {
            var url;

            // Trigger the AJAX GET request that passes the information
            // to the server (using jQuery)
            $.get(
                url = '/blog/how-to-use-ajax-to-update-forms-without-pressing-submit.html?'
                    + '&name='     + encodeURIComponent(opt.name)
                    + '&age='      + encodeURIComponent(opt.age)
                    + '&location=' + encodeURIComponent(opt.location)
            );

            
            // Add a note to the page that it has been saved
            $('span#savednote')
                .text('Information has been saved')
                .animate({
                    opacity: 1
                });


            // Fade out the note after 5 seconds
            setTimeout(function ()
            {
                $('#savednote').animate({
                    opacity: 0
                }, 250);
            }, 5000);


            // Now, at the end of the timer function, clear any reference
            // that we have of the timer
            TIMERS.SAVEDATA = null;
        }, 1000);
    }
</script>

The PHP code

The PHP server-side code that saves the information that's passed to it is quite simple and, in this example, only stores it in the session. In reality you'd store the information in a database or in a file on disk so that you don't lose it.

<?php
    require_once('common.php');
    
    session_start();
    
    // The front-end AJAX code sends everything whenever a key is pressed - so
    // store it all. Normally you'd put the information into a database or
    // in a file on disk.
    if (isset($_GET['age']) OR isset($_GET['name']) OR isset($_GET['location'])) {
        $_SESSION['autosave-forms-age']      = $_GET['age'];
        $_SESSION['autosave-forms-name']     = $_GET['name'];
        $_SESSION['autosave-forms-location'] = $_GET['location'];
    }
?>

A basic example page showing everything together

There's an example page here. The page is fully self-contained - you'll find everything that you need is in the source code (including the smidgen of PHP code).

An alternative to making AJAX requests on every keypress

Whilst strictly speaking the code doesn't make an AJAX request on every single keypress - it can still result in a lot of requests. You can, however, get around this by batching up the requests and sending all of the data as one when a submit button is pressed. This makes the whole process more like a traditional form. It might also make the form a bit more straight-forward as it looks to be more like a traditional form (ie with a submit button).

Another way of reducing network traffic is to increase the timeout before the AJAX requests are initiated. This means that the likelyhood of more data being entered into the form before requests are made is higher - and thus fewer requests are made.

An alternative to sending data back to the server

An alternative to sending the data back to the server every so often via AJAX is to store the form data in the browsers window.localStorage variable. The form can then be just a regular form but using the window.localStorage variable as a kind of a temporary backup. So if the page is inadvertently refreshed you can fill the form elements with whatever is stored in the window.localStorage variable (overriding whatever the server sends).

When the form is submitted it sends the data to the server as usual and you also clear the window.localStorage variable so things don't get confused.

It would be useful to have an option to clear the locally stored data and revert to whatever information that the server sends.

Performance concerns

The main thing here is the abundance of AJAX requests that are generated - which may be more of a concern when targetting mobile devices. As detailed above though - this can be circumvented in a few ways by increasing the delay before the AJAX requests are generated or by only sending the AJAX request when all form fields have been filled out. Both of these methods will reduce the amount of network traffic that's generated.

Usability concerns

Even though this way of saving data is easier to use (IMO) - the fact that users are used to pressing a submit button to save their data means that this way of working may add a little confusion (users might be left looking for a submit button for example).

You can easily get around this though in a few ways:

  1. Add a fake save button that doesn't actually do anything except for triggering a "Your data has been saved" message.
  2. Have a real save button that triggers the AJAX request that sends the data to the server and then presents the user with a "Your data has been saved" message.
  3. Whenever the JavaScript function that sends the data to the server runs have it present the user with a saved message just underneath the form input. This message could fade out slowly after 5 seconds.

Conclusion

This technique of handling forms may be better suited to settings pages - where you don't have to create new records - just update existing ones.

Users will most likely be expecting to see a save button - and the lack of one may lead to confusion. But this confusion can be allayed by using quite visible prompts alerting the user to the fact that their information has been saved.

For internal admin type settings pages - I've found that it can be very useful. It takes a bit more code - but the usability gains that it provides are well worth it.