2014-02-28 122 views
5

我有一些在我的代码点在那里我有对相关的开始和结束日期字段(范围)的。我需要验证开始是在结束日期之前。我正在使用jQuery验证插件。jQuery验证日期范围问题

这里是我的代码:http://jsfiddle.net/jinglesthula/dESz2/

标记:

<form id="myform"> 
    <input type="text" name="startDate" id="startDate" class="validDate" /> 
    <br/> 
    <input type="text" name="endDate" id="endDate" class="validDate" /> 
    <br/> 
    <input type="submit" /> 
</form> 

JS:

$(function() { 
    // simple date mm/dd/yyyy format 
    $.validator.addMethod('validDate', function(value, element) { 
    return this.optional(element) || /^(0?[1-9]|1[012])[ /](0?[1-9]|[12][0-9]|3[01])[ /][0-9]{4}$/.test(value); 
    }, 'Please provide a date in the mm/dd/yyyy format'); 

    $.validator.addMethod('dateBefore', function(value, element, params) { 
    // if end date is valid, validate it as well 
    var end = $(params); 
    if (!end.data('validation.running')) { 
     $(element).data('validation.running', true); 
     this.element(end); 
     $(element).data('validation.running', false); 
    } 
    return this.optional(element) || this.optional(end[0]) || new Date(value) < new Date(end.val()); 

    }, 'Must be before corresponding end date'); 

    $.validator.addMethod('dateAfter', function(value, element, params) { 
    // if start date is valid, validate it as well 
    var start = $(params); 
    if (!start.data('validation.running')) { 
     $(element).data('validation.running', true); 
     this.element(start); 
     $(element).data('validation.running', false); 
    } 
    return this.optional(element) || this.optional(start[0]) || new Date(value) > new Date($(params).val()); 

    }, 'Must be after corresponding start date'); 
    $('#myform').validate({ // initialize the plugin 
    rules: { 
     startDate: {dateBefore: '#endDate', required: true}, 
     endDate: {dateAfter: '#startDate', required: true} 
    }, 
    submitHandler: function (form) { // for demo 
     alert('valid form submitted'); // for demo 
     return false; // for demo 
    } 
    }); 
}); 

我想让它这样,每当一个日期字段的变化,我做的检查确保范围有效(例如,开始<结束)。

我碰到的是,如果我输入一个有效范围,然后将结束日期的年份更改为开始日期的年份之前的一年,它将清除开始日期中的错误,但不清除结束日期字段上的错误。我已经调试并进入dateAfter方法,并看到它返回true!我甚至可以(无需进一步修改字段值)点击提交按钮,然后清除错误并提交表单。

任何想法,为什么它不清除呢?

编辑为了进一步澄清,我正在重现步骤:

  1. 输入起始场2014年1月1日(第一个)
  2. 在进入2015年1月1日结束现场
  3. 更改最终场5年到3
  4. 选择3和5型再次
  5. 开始现场清除它的错误,但最终还是在抱怨的范围开始/ EN d
  6. 点击或标签进行模糊最终场 - 仍然没有错误的结算
  7. 点击结束领域
  8. Shift + Tab键回到起点领域
  9. 结束字段现在(终于)清除错误信息(你也可以提交表单,看看它清除月底场误差)
  10. 围? 0 wai ?? !!!! ??!?? !!! 111 !!!一个!!!! 11 !!! 1 !!!
+0

其他注意事项:我想要的是当范围无效时,两个字段都将失效,并且一旦该余额恢复,两个字段都将重新验证。数据('validation.running',bool)是为了避免无限循环。用户可以通过改变开始或结束来恢复平衡。 – jinglesthula

+0

我无法用给出的步骤重现您的问题。在步骤7-8结束消息不清除。 – Ryley

+0

抱歉有关混淆!我已经更新了步骤以更好地反映我正在做的事情。事实上,结束消息不清楚(即使我正在观察dateAfter方法运行并返回true,它也不应该这样做)是问题所在。步骤5是首先证明问题的地方。第9步是问题没有发生的地方(这令人沮丧,为什么它会在那里工作,而不是回到步骤5)。 – jinglesthula

回答

3

啊,想通了(或者至少解决了这个问题)。验证插件可能没有被设计为允许验证给定字段的方法运行中的第二个字段。也许有一个内部参考目前正在验证的领域,所以你需要做验证串行而不是重叠它们。

我已经在这里添加了一个更新的小提琴在这里你可以看到使用的setTimeout,以确保“其他领域”验证后的第一个确实清除了问题:http://jsfiddle.net/jinglesthula/dESz2/3/

this.element(end); 

变得

setTimeout($.proxy(
    function() { 
    this.element(end); 
    }, this), 0); 

我还添加了一个setTimeout来清除'validation.running'标志,以确保在'other'字段验证之后它不会被清除。

+0

注意:proxy()调用是为了确保'this'是正确的上下文,在这种情况下是验证器实例。 – jinglesthula