“Formless” HTML Forms

Although forms are traditionally created using the HTML form element, there is a new approach that uses AJAX in place of the form element. Long story short: The new approach supports a more logical organization of code, but the auto-fill capabilities of browsers only work with form elements, so there are cases where form element is still needed.

I'll start with the new formless forms, then show how their behavior can be imitated using the HTML form element in place of AJAX, then finally compare the relative merits of the two approaches and consider the possibility of an HTML future without the venerated HTML form element.

Formless forms based on AJAX

Here is the basic layout of a formless form:

<!– start of form –>
   <label class='input-label' id='elem1Label'>text1
      <input type="text" class="input"
         id="elem1"></label><br>
   <!– .  .  . additional form elements .  .  . –>
   <button type="button" class="button"
      onClick="doForm()">SUBMIT</button>
<!– end of form –>

The form is missing its HTML form element, as form submission is handled by the JavaScript doForm function instead.  What the form does have are familiar content-editable elements such as input, select, textarea, and so forth.

The doForm function has three parts: preliminary checks before form submission, the actual submission via AJAX, and post processing after the submission. In this illustration, the preliminary checks just see that the user has provided some sort of input. The actual form submission relies on an AJAX call accomplished via the really simple rsAjax interface.

<script type=text/javascript>
   function doForm() {
      var input1 = getAndCheckValue('elem1')
      // . . . additional element checks . . .
      if (input1 && input2 && . . .)
         rsAjax({
            url: 'formScript.ajax.php',
            data: {
              input1: input1,
              input2: input2,
              .  .  .  .  .
            },
            success: processAjaxResponse
         })
         // formScript.ajax.php processes the form
         // parameters and provides a response.
 
      function processAjaxResponse(response){
         if (!response.error) {
            window.location.assign('someNewPage.php');
            return
         } else {
            // diagnostics upon failure …
         }
      }
   }
</script>

In the interests of full disclosure, there is one additional detail. After the user enters the last input in a form, hitting the return key triggers form submission. To make this happen in a formless form, it is necessary to add to the last input element something like onKeyPress="checkForReturnKey(event)", where the requisite event handler is:

function checkForReturnKey(evt) {
   if (evt.keyCode && evt.keyCode == 13) doForm()
}

Using the HTML form element

We next consider using an HTML form element. When the form is submitted, the server response is an arbitrary HTML page, but if there are user errors, it is necessary to return to the same page in order to provide corrective feedback to the user. So the same page may be displayed in two different ways. We will use the POST method for submitting the form. Since the page is initially displayed using the GET method, this gives us a convenient way of distinguishing the two ways of displaying the page.

The first step after the form is submitted is to invoke server side processing by including the script formScript.form.php, which is basically just the formScript.Ajax.php without the AJAX interface.

In the event that a new page is to be opened, this is done up front in PHP, in order to avoid pointlessly repainting the current page before opening the new one. This is why the response to form submission has to come first, before the form itself.

Diagnostics in case of failure are now handled in PHP rather than JavaScript, and they are typically interleaved with the HTML code.

<?php
    global $_RESPONSE;
    $_RESPONSE['error'] = 'false';
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
       require('formScript.form.php');
    }
    if (!$_RESPONSE['error'])
       header('Location: ' . someNewPage.php);
?>
   .  .  .  .  .  .
<?php
   if ($_RESPONSE['error'])
     // echo diagnostics upon failure

?>

Preliminary checking of user inputs is now handled by the checkForm() function. The form's action is the default, namely to reload the page via the POST method. The form's input elements now include PHP snippets whose purpose is to remember user input values in the event that there has been an error. And of course the submit button is now of type submit.

<form method="post"
   onsubmit="return checkForm()" class="form">
   <label class='input-label' id='elem1Label'>text1
      <input type="text" class="input" id="elem1"
         name="input1"
         value="<?php if (isset($_POST['input1']))
            echo $_POST['input'];?>">
</label><br>
   <!– .  .  . additional form elements .  .  . –>
   <input value="SUBMIT" type="submit">
</form>

Relative Merits

Client-server separation. The main advantage of the formless form is that there is a clean separation between client-side JavaScript processing and server-side PHP processing. By contrast, the use of the traditional form element requires an intermingling of PHP with HTML and JavaScript.

Temporal order. With formless forms, processing can be laid out in temporal order: (1) the user fills out the form, (2) the "doForm" function checks to see that the form has been filled out and (3) ships the user's inputs to the server, (4) the server responds to user input, and (5) the client responds to the results of the server's processing via the processAjaxResponse function.

By contrast, the approach using the HTML form element begins with Step (4) in which the server responds to the user inputs. Next, we encounter Step (1), where the user fills in the form, followed by Step (2), checking the user's inputs via the checkForm function. Then comes a new step of intermingling user inputs with form elements, followed by Step (3), submitting the form inputs to the server. Step (3) is a little simpler than before, as the input elements to be passed to the server are explicitly marked by the presence of the form element. Finally, Step (5), which provides corrective feedback, is intermingled with the HTML; it's precise location depends on how feedback is delivered.

Format Neutrality. The form element contains in its definition certain formatting characteristics that may need to be neutralized in standards-based browsers. In one application, I was obliged to declare the following special class for use with forms:

<style type="text/css">
   .form { position: relative; left:-32px;
           margin-top: -32px }
</style>
<!–[if IE]>
<style type="text/css">
   .form { position:relative; left: 0px;
           margin-top: -32px }
</style>
<![endif]–>

Password Auto-fill in HTML forms. In the case of a login form, the browser will ask the user's preference for remembering passwords, paint the password field and the previous field with a yellow background, and fill them in from remembered information. This behavior is lost in the case of formless forms. Of course, one can program the formless form to remember passwords, but that's a fair amount of work. Usually, it's easier to just use the HTML form element. An exception would be where the login form has white letters on a dark background — switching to a light yellow background destroys both esthetics and readability. In this exceptional case, formless forms can provide a straightforward end run around the browser's effort to be helpful.

Spurious refresh messages. If you use an HTML form, and the user hits the submit button and then the refresh key (F5 on Windows), the user will see the following wordy message, independently of what page the submit action has displayed:

Confirm Form Resubmission

The page that you're looking for used information that you
entered. Returning to that page might cause any action you took
to be repeated. Do you want to continue?

This cryptic message appears even if the "page that you're looking for" is a completely static HTML page! Happily, formless forms don't carry this burden of unnecessary guilt.

A future without form elements?

The existing conventions for browser auto-fill are jerry-rigged. What's needed is an explicit convention for marking form elements that should be remembered, e.g., value=remember, in the case of address fields, or value=remember-for-page, in the case of user id and password. The question about whether the user wants to remember would come whenever the page is unloaded. Since these suggested conventions work at the element level rather than the form level, they make sense for both "formless" forms and for traditional form elements.

An illustrative example

The login plug-in I wrote uses a traditional HTML form for the actual login, but uses formless forms for a half dozen other forms. The interested reader is invited to download the zip file and have a look at the files to get a first hand view of the relative complexity of the two approaches.

About PageNotes

My biographies are here and here.
This entry was posted in javaScript Programming, Web Design. Bookmark the permalink.

2 Responses to “Formless” HTML Forms

  1. Jacqueline says:

    我喜欢,顶一个!

  2. lynn says:

    Good blogging!