form-submit soup

2008-02-05 @ 17:58#

updated:2008-03-01

posted an example of a 'safe' reset button.

doing a HTML form submit via javascript events is not always easy or consistent - esp. when you want to do some client-side validation before the submit. this came up again today w/ a colleague and i figured i'd post the details here for future reference.

first, there are five (that i can count) common element that you can use to submit a form POST to the server:

  1. <input type="submit" ... />
  2. <input type="button" ... />
  3. <input type="image" ... />
  4. <button ... />
  5. <a ... />

and there are *four* different ways to script the above five elements. here's my examples:

the <input type="submit" ... /> is the case where you add a submit button to the form. all you need to do is wire up your validate method to the onsubmit event of the *form* that wraps the submit button. where validateForm is a method that returns true|false, you do it like this:

// works for input type="submit"
// link validate to the *form*
f = document.getElementsByTagName('form')[0];
if(f)
{
  f.onsubmit = validateForm;
}

the <button ... /> and <input type="image" ... /> work slightly differently. in these cases, you wire the validateForm method to the onclick event of the *elements* themselves, not the form in which they reside. where you have both these elements with an attribute setting of name='submit-element', you do it like this:

// works for button and input type="image"
// link validate method to the *element*
coll = document.getElementsByName('submit-element')
for(i=0;i<coll.length;i++)
{
  coll[i].onclick = function()
  {
    return validateForm();
  };
}

the <input type="button" ... /> case requires a bit more work. in this case, you need to wire the validateForm method to a new function that will execute the validateForm method; evaluate the results (true|false); and, if true, execute the submit() method of the form. using an anonymous function for elements with an attribute setting of name='button', you do it like this:

// works for input type="button"
// link validate method to the element 
// *and* execute submit
coll = document.getElementsByName('button')
for(i=0;i<coll.length;i++)
{
  coll[i].onclick = function()
  {
    if(validateForm())
    {
      f.submit();
    }
  };
}

finally, in the case of anchor elemements (a), you need to do all the same work you did for the button element *and* you need to perform a return false; at the end of the function to prevent the click event from bubbling up and causing the page to scroll to the top. this 'bubbling' also can cause the appearance of the '#' in the browser URL on some clients. here's how the code looks for handling anchor elements:

// works for anchor tag
// link validate method to the element, 
// execute submit *and* return false;
coll = document.getElementsByTagName('a')
for(i=0;i<coll.length;i++)
{
  coll[i].onclick = function()
  {
    if(validateForm())
    {
      f.submit();
    }
    return false; // prevents # in the URL line
  };
}

all simple, right [g]? you can check out a working example of this to confirm it works for your browser flavor. to see the full code set and markup, just to a view source on the sample page.

code