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

Written by Richard Heyes, on 12th September 2017

In addition to the speed benefits that come from automatically saving form fields, it makes for a nicer 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 so 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 the forms that you create... today!

Is it more involved? Well there's a little more to it - and it'll probably take a little while to get used to it - making your forms this way. But once you are, 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 little PHP that takes the default values for the form fields out of the session. If you're 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 via 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 request. If you have a lot of data you could use POST here
    // instead of GET.
    //
    function saveformdata()
    {
        // Get the form information and put it in our state variable.
        var opt = {
            name:     document.getElementById('name').value,
            age:      document.getElementById('age').value,
            location: document.getElementById('location').value
        };

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

        // Create the new timer - which runs after a delay of one 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 message to the page that it has been saved
            $('span#savednote')
                .text('Information has been saved')
                .animate({
                    opacity: 1
                });


            // Fade out the message 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 PHP 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
    // into 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 little bit 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 likelihood of more data being entered into the form before requests are made is higher - meaning 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 amount of AJAX requests that are generated - which may be more of a concern when targeting 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 by the form.

Usability concerns

Even though this way of saving data is easier to use (IMO) - the fact that users are accustomed 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 five 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 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.