Javascript表单验证仅适用于Firefox

时间:2010-05-28 17:57:09

标签: javascript validation forms cross-browser onsubmit

我对Javascript比较陌生,所以我希望这是一个简单的错误。我构建了一个在表单的onSubmit上调用的泛型表单验证函数。该函数遍历所有表单的子元素,查找某些类,并分析相应字段的内容。如果发现丢失或错误的内容,它会显示相应的错误消息div并返回false,从而阻止将表单提交到php页面。

它在firefox 3.6.3中运行良好,但在我测试过的所有其他浏览器中(Safari 4.0.4,Chrome 4.1,IE8)它似乎忽略了onSubmit并直接跳转到php处理页面。

HTML CODE:

    <form name='myForm' id='myForm' action='process_form.php' method='post' onSubmit="return validateRequired('myForm')">

   <fieldset class="required radioset">
    <label for='selection1'>
     <input type='radio' name='selection' id='selection1' value='1'/>
     Option 1
    </label>
    <label for='selection2'>
     <input type='radio' name='selection' id='selection2' value='2'/>
     Option 2
    </label>
    <label for='selection3'>
     <input type='radio' name='selection' id='selection3' value='3'/>
     Option 3
    </label>
    <label for='selection4'>
     <input type='radio' name='selection' id='selection4' value='4'/>
     Option 4
    </label>
    <div class='errorBox' style='visibility:hidden'>
     Please make a selection
    </div>
   </fieldset>

   <fieldset class="required checkset">
    <label>
     Choice 1
     <input type='checkbox' name='choices' id='choice1' value='1'/>
    </label>
    <label>
     Choice 2
     <input type='checkbox' name='choices' id='choice2' value='2'/>
    </label>
    <label>
     Choice 3
     <input type='checkbox' name='choices' id='choice3' value='3'/>
    </label>
    <label>
     Choice 4
     <input type='checkbox' name='choices' id='choice4' value='4'/>
    </label>
    <div class='errorBox' style='visibility:hidden'>
     Please choose at least one
    </div>
   </fieldset>


   <fieldset class="required textfield" >
    <label for='textinput1'>
     Required Text:
     <input type='text' name='textinput1' id='textinput1' size='40'/>
    </label>
    <div class='errorBox' style='visibility:hidden'>
     Please enter some text
    </div>
   </fieldset>

   <fieldset class="required email textfield">
    <label for='email'>
     Required Email:
     <input type='text' name='email' id='email' size='40'/>
    </label>
    <div class='errorBox' style='visibility:hidden'>
     The email address you have entered is invalid
    </div>
   </fieldset>


   <div>
    <input type='submit' value='submit'>
    <input type='reset' value='reset'>
   </div>

  </form>

JAVASCRIPT CODE:

    function validateRequired(id){

 var form = document.getElementById(id);
 var errors = 0;
 var returnVal = true;
 for(i = 0; i < form.elements.length; i++){
  var elem = form.elements[i];
  if(hasClass(elem,"required")){

   /*RADIO BUTTON or CHECK BOX SET*/
   if(hasClass(elem,"radioset") || hasClass(elem,"checkset")){
    var inputs = elem.getElementsByTagName("input");
    var check = false;
    for(j = 0; j < inputs.length; j++){
     if(inputs[j].checked){
      check = true;
     }
    }
    if(check == false){
     errors += 1;
     showError(elem);
    } else {
     hideError(elem);
    }
   }

   /*TEXT FIELD*/
   else if(hasClass(elem,"textfield")){
    var input = elem.getElementsByTagName("input");
    if(input[0].value == ""){
     errors += 1;
     showError(elem);
    } else {
     hideError(elem);

     /*EMAIL ADDRESS*/
     if(hasClass(elem,"email")){
      if(isValidEmail(input[0].value) == false){
       errors += 1;
       showError(elem);
      } else {
       hideError(elem);
      }
     }
    }
   }
  }
 }
 if(errors > 0){
  returnVal = false;
 } else {
  returnVal = true;
 }
 return returnVal;}

我知道这需要查看很多代码,但任何帮助都会受到赞赏。由于它在一个浏览器中工作正常,我不知道如何开始调试。 谢谢 安德鲁

6 个答案:

答案 0 :(得分:1)

for(i = 0; i < form.elements.length; i++){
    var elem = form.elements[i];
    if(hasClass(elem,"required")){

问题是您的required和其他类放在<fieldset>元素上。

Fieldset元素包含在IE,Firefox和Opera的form.elements集合中,但不包含在WebKit浏览器(Chrome,Safari)中。正是这些浏览器让我的表单失败了。

<fieldset>集合中包含elements一直是一个奇怪的怪癖。 DOM Level 2 HTML规范声明只有'表单控件元素'应该出现在集合中,而HTML4's definition似乎不包含没有控件名称或值的字段集。

您可以更改代码以使用getElementsByTagName来代替字段集:

var fieldsets= form.getElementsByTagName('fieldset');
for (var i= 0; i<fieldsets.length; i++) {
    var elem= fieldsets[i];

答案 1 :(得分:1)

我不会使用hasClass。这是另一种尝试的方法,可能更适合您:

var node_list = document.getElementsByTagName('input');
for (var i = 0; i < node_list.length; i++) {
    var node = node_list[i];

    if (node.getAttribute('type') == 'text') {
        // do something here with a <input type="text" .../>
        alert(node.value);
    }
} 

我知道IE从一些具有多个与之关联的类的元素中获取类是有问题的。无论如何,这是一个方便的功能。

答案 2 :(得分:0)

如果您有任何类型的JavaScript错误,该函数将不会返回false,因此将触发提交数据的默认行为。

首先尝试运行代码[http://www.javascriptlint.com/online_lint.php][1],然后运行调试器。

答案 3 :(得分:0)

尽量不要使用if(errors&gt; 0)...只是在每个条件下(对于错误的输入)put return false; 并且在最后一个括号之前的结尾处返回true; 并且更好地使用:

onSubmit="return validateRequired(this)"

并且不需要这行(如果你删除了错误var)

 var form = document.getElementById(id);
 var errors = 0;
 var returnVal = true;

答案 4 :(得分:0)

不是问题的原因,我敢肯定,但最好不要在没有选择其中一个的情况下提供一组单选按钮。

在您的特定情况下,如果您知道在服务页面时设置了一个,则不需要“必需”检查;用户无法将单选按钮置于没有选中的状态。选择合理的默认值,将其作为第一个选项,然后选择它。简化你的生活:)

来自W3C:

http://www.w3.org/TR/html401/interact/forms.html#radio

  

如果集合中没有单选按钮   最初使用相同的控件名称   “on”,用户代理行为选择   哪个控制最初“开启”是   未定义。注意。既然存在   实现处理这种情况   不同的是,目前的规范   与RFC 1866不同([RFC1866]       第8.1.2.4节),其中规定:

At all times, exactly one of the radio 
buttons in a set is checked. If
none of the <INPUT> elements of a set
of radio buttons specifies `CHECKED',
then the user agent must check the
first radio button of the set
initially.
     

由于用户代理行为不同,   作者应确保在每一组中   一个最初的单选按钮   “导通”。

答案 5 :(得分:0)

回到基础知识一秒钟:你说它“似乎忽略了onsubmit”。这留下了我能想到的三种可能性:

  1. 您的功能永远不会被称为
  2. 它被称为,由于错误而在中途轰炸
  3. 它被称为,并没有按照你的想法行事,总是回归真实
  4. 从你的问题中不清楚它是什么,所以如果我是你,我会通过在函数开头发出一个警告来开始调试,以查看IE是否正在调用它 - 然后将警报调低并运行再次验证,并查看它停止出现的位置(任何错误必须高于该点)。

    我还想提醒它被调用的地方的返回值,以查看返回的内容。如果它始终是真的,那么你的代码正在运行,但没有按照你的想法去做。

    从那里开始,你至少可以更清楚地了解正在发生的事情,如果不是要仔细检查的确切代码块。