function getFormData()
{ 
  var optionValue = function (option) 
  {
    return option.hasAttribute('value') ? option.value : option.text; 
  }

  var getValue = function (element) 
  {
    switch (element.tagName.toLowerCase()) 
    {
    case 'input':
      switch (element.type.toLowerCase()) 
      {
        case 'checkbox':
        case 'radio':
          return element.checked ? element.value : null;
        default:
          return element.value;
      }
      break;
    case 'select':
      if (element.type === 'select-one') 
      {
        var index = element.selectedIndex;
        return index >= 0 ? optionValue(element.options[index]) : null;
      }
      else 
      {
        var length = element.length;

        if (!length)
          return null;

        var values = [];

        for (var i = 0; i < length; i++) 
        {
          var option = element.options[i];
          if (option.selected)
            values.push(optionValue(option));
        }
        return values;
      }
      break;
    case 'button':
    case 'textarea':
      return element.value;
    }
    return null;
  }
  
  var form = document.forms[0];
   
  var elements = document.getElementsByTagName('*');
  var result = '';
  var element, key, value;
  var submitted = false;

  for (var i = 0; i < elements.length; i++)
  {
    element = elements[i];

    if (!element.disabled && (element.name || element.id) && element.style.display != 'none')
    {
      key = element.name || element.id;
      value = getValue(element);

      if (value !== null && element.type !== 'file')
      {
        if (element.type === 'submit')
        {
          if (submitted) {continue;}
          else {submitted = true;}
        }
		var escapedValue = escape(value);		
		escapedValue = escapedValue.split('+').join('%2b');
		//TODO: whether we need to encode '/'?
		//TODO: whether we need to encode '='?
		result = result + (result === '' ? '' : '&') + escape(key) + '=' + escapedValue;
      }
   }
  }
  return result;
}
getFormData()