2014-02-28 120 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