循环功能会导致错误,并在第一次更改时失败

时间:2014-10-21 14:04:57

标签: javascript jquery html forms validation

我这里有以下脚本导致我出错:

var sections = ["#general_info", "#address_records", "#employment_history", "#driver_experience", "#military_experience", "#eeo_survey", "#psp_notice", "#eva"];
for(var i = 0; i < sections.length; i++){ 
    $(sections[i]).find('input, select').each(function(){
        $(this).change(function(){
            validate();
            $(this).closest('.placement').find('.module-heading').removeClass('module-heading-bad');
            $(this).closest('.placement').find('.glyphicon').addClass('glyphicon-ok text-success');
            $(this).closest('.placement').find('.glyphicon').removeClass('glyphicon-warning-sign text-danger');
            $(sections[i]).find('input, select').each(function(){
                if($(this).closest('div').hasClass('has-error')){
                    $(this).closest('.placement').find('.module-heading').addClass('module-heading-bad');
                    $(this).closest('.placement').find('.glyphicon').addClass('glyphicon-warning-sign text-danger');
                    $(this).closest('.placement').find('.glyphicon').removeClass('glyphicon-ok text-success');
                    return false;
                }
            });
        });
    });
}

function validate(){
    var driving_qs = ['driving_exp_qa', 'driving_exp_qb', 'driving_exp_qc', 'driving_exp_qd'];
    for( var i = 0; i < driving_qs.length; i++){
        if($('input[name='+driving_qs[i]+']:checked').val()){
            $('input[name='+driving_qs[i]+']').closest('.form-group').removeClass('has-error');
            $('input[name='+driving_qs[i]+']').closest('.form-group').addClass('has-success');
        }else{
            $('input[name='+driving_qs[i]+']').closest('.form-group').addClass('has-error');
            $('input[name='+driving_qs[i]+']').closest('.form-group').removeClass('has-success');
        }
    }
    var fields = [{
        selector: $('.not-empty'),
        validations: [ isNotEmpty]
    },{
        selector: $('.email'),
        validations: [ isNotEmpty, isEmail]
    },{
        selector: $('.number'),
        validations: [ isNotEmpty, isNumber]
    },{
        selector: $('.number-noreq'),
        validations: [isNumberNotRequired]
    }];
    $('.form-control').closest('div').removeClass('has-error');
    var i = 0, k = 0, z = 0, j = fields.length, item, selector, fn, info;
    for(; i < j; i++){
        item = fields[i];
        for(k = 0; k < item.validations.length; k++){
            fn = item.validations[k];
            for( z = 0; z < item.selector.length; z++){
                selector = $(item.selector[z]);
                info = selector.closest('div');
                if(info)
                    var result = fn(selector.val());
                if(result){
                    info.removeClass("has-error");
                    info.addClass('has-success');
                }else{
                    info.removeClass('has-success');
                    info.addClass("has-error")
                }
            }
        }
    }
}

如果我在没有前面的for循环的情况下运行脚本,那么脚本运行得非常好。以下是我的代码所做的一步一步(注意:这没有for循环):

  1. 在代码中找到该部分,并在每个输入中找到一个选择字段
  2. 将更改事件分配给每个目标输入并选择字段
  3. 在更改时找到最接近的类位置范围,并对第一个模块标题进行精细处理并执行所有类的添加和删除,只需在下面没有错误的情况下将标题刷新到成功标题。
  4. 查找所有输入并选择并检查错误,如果它们存在则返回false,并将错误类别添加回所有内容
  5. 这个脚本将一直工作到每个部分的结尾,就像它应该做的那样。但是,在我尝试使用for loop执行此操作后,它仅在一次输入后创建了成功方案。为什么会发生这种情况,甚至可能在我正在进行的循环中使用此函数?

    下面我还包括了html标记的样本

    <!-- this tag serves no purpose other than being a bookmark for scripting -->
    <span class='placement'>
        <!-- Section 1: General Information  -->
        <div id='general-heading' class='row module-heading module-heading-bad general' data-toggle='#general_info'>
            <div class='form-group'>
                <div class='col-md-12'>
                    <h4 class='text-info '>General Information<div id='general-confirmation' class='glyphicon glyphicon-warning-sign pull-right text-danger'></div></h4>    
                </div>
            </div>
        </div>
        <div id='general_info' class='app-section'>
            <div class='form-group'>
                <div class='col-xs-12'>
                    <div class='form-group row'>
                        <div class='col-sm-6 col-xs-12'>    
                            <label class='control-label'>First Name<span class='req'> *</span></label><br />
                            <input type='text' class='form-control not-empty' id='first_name' value="<?=$first_name?>"/>
                        </div>
                        <div class='col-sm-6 col-xs-12'>
                            <label class='control-label'>Middle Name</label><br />
                            <input type='text' class='form-control' id='middle_name' value="<?=$middle_name?>"/>
                        </div>
                    </div>
                </div>
            </div>
    </span>
    

    如果您需要更多信息,说明或代码,请与我们联系。我真的很想尝试解决这个问题,所以非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

此代码块中的问题:

for(var i = 0; i < sections.length; i++){ 
    $(sections[i]).find('input, select').each(function(){
        $(this).change(function(){
            ...
            $(sections[i]).find('input, select').each(function(){
                ...
                }
            });
        });
    });
}

它是否使用变量i,当function()运行change时,变量会发生变化。

在您的情况下,最简单的方法是使用forEach函数而不是for循环,而不是使用索引:

sections.forEach(function(section){ 
    $(section).find('input, select').each(function(){
        $(this).change(function(){
            ...
            $(section).find('input, select').each(function(){
                ...
                }
            });
        });
    });
})

这样可以确保您的i每次都不同。