2010-12-03 69 views
13

我使用jQuery.validate v 1.6.0來驗證我的表單。jQuery驗證textarea maxlength bug

我的一個數據庫字段限制爲1000個字符。我加了驗證,相應的textarea這樣的:

在我的網頁的標題,我想補充

$('form.validate').validate(); 

在我的網頁,我宣佈:

<form method="post" class="validate" action="Save"> 
    <textarea name="description" minlength="15" maxlength="1000" id="description" class="required"></textarea> 
    <input type="submit" value="Save">  
</form> 

我的問題遇到的問題是,jQuery似乎將與新數據庫不同的'新行'所涉及的字符數量計算在內。

當我輸入完全沒有新行的1000個字符時,一切都很順利,驗證工作。如果我用一些新行鍵入1000個字符,jQuery允許POST發生,但是我的數據庫拒絕插入/更新,因爲數據太大。

任何提示將不勝感激。

+0

我遇到這個問題。真的很驚訝,更多的人不會遇到這個! – 2011-11-29 16:08:43

+0

還要注意,jquery驗證器「修剪」內容,例如尾隨空格和換行符不計算 – nuander 2013-03-06 15:41:12

回答

-5

刪除服務器驗證並僅保留客戶端驗證。 在html新行= 3字符 在數據庫中新行= 1字符 所以你必須保持一個時間。 或更改db字符設置

+1

刪除服務器驗證?你一定是在開玩笑吧?你有沒有嘗試過像tamperdata一樣簡單的事情? =>只有客戶端驗證是對各種黑客行爲的敞開大門。 – grootjans 2011-01-04 22:20:19

+0

您可以信任的唯一驗證是serverside。如果你放棄任何驗證,它應該是客戶端驗證。 – Falle1234 2011-11-18 08:04:48

2

雖然這不是客戶端方案,但我能夠處理問題服務器端。

我基本上是去掉「\ r」字符的「額外」字符。我猜這些不會計入瀏覽器中的字符串長度,或者與「\ n」字符組合爲一個字符串。

在我的情況下,ASP.NET MVC與C#:

[HttpPost] 
public ActionResult SetComment(int id, string comment) 
{ 
    // Yep, the browser can insert newlines as "\r\n" which overflows the allowed number of characters! 
    comment = comment.Replace("\r", ""); 

    // More code... 
} 
1

我來到防空火炮的同類問題。這是由於在javascript中,field.length會返回字符數,但一個字符可以使用2字節來存儲信息。

我的問題是數據庫中的VARCHAR2字段只能存儲4000Bytes的信息或2000Characters。 我們很容易混淆,並認爲我們可以在這類字段中存儲4000個字符。

我認爲在你的情況下,該字段不限於1000個字符,而是1000個字節,它只是與使用一個字節信息的「標準字符」相同,所以我將限制爲2000Bytes並保持javascript驗證1000chars。 然後,當然,我會反對以前的答案,並對字符數進行服務器端驗證。

當然你還有其他的解決方案,例如我沒有使用Jquery,我調整了字符計數器來計算每個特殊字符兩次(這個問題影響到換行符,但也有重音符... )

1

我也採取了像John Bubriski那樣的服務器端方法,但是在ASP中實現了它。如果這僅僅是在<textarea>隨後的情況發生,請

ModelBinders.Binders.DefaultBinder = new NewlinesNormalizingModelBinder(); 
-1

:NET MVC作爲一個擴展DefaultModelBinder,使所有控制器的行動將立即受益:

public class NewlinesNormalizingModelBinder : DefaultModelBinder 
{ 
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) 
    { 
     base.BindProperty(controllerContext, bindingContext, propertyDescriptor); 

     // Note: if desired, one could restrict the conversion to properties decorated with [StringLength]: 
     // && propertyDescriptor.Attributes.OfType<StringLengthAttribute>().Any() 
     if (propertyDescriptor.PropertyType == typeof(string)) 
     { 
      var originalString = propertyDescriptor.GetValue(bindingContext.Model) as string; 
      if (!string.IsNullOrEmpty(originalString)) 
      { 
       var stringWithNormalizedNewlines = originalString.Replace("\r\n", "\n"); 
       propertyDescriptor.SetValue(bindingContext.Model, stringWithNormalizedNewlines); 
      } 
     } 
    } 
} 

然後在應用程序啓動使用以下代碼:

$(document).ready(function() { 
      $("input[type=submit]").live("click", function (e) { 
       if ($(textarea).val().length > 1000) { 
        e.preventDefault(); 
        return false; 
       } 
      }); 
     }); 

這一定會起作用。

4

我使用jQuery Validate 1.9來交叉這個問題。因爲我在服務器上使用ASP.NET MVC 3和C#,在服務器上的換行符是「\ r \ n」,但客戶端上是「\ n」。當我在客戶端上驗證我的textarea時,驗證沒有失敗,因爲「\ n」只被計算爲一個字符,但當文本在線路斷點爲「\ r \ n」的服務器上進行驗證時,驗證將失敗。

我soultion這個問題是重寫jQuery驗證方法「rangelengt」因爲我也有定義的最小長度:

$.validator.addMethod('rangelength', function (value, element) { 
     var maxlen = parseInt($(element).attr('data-val-length-max')); 
     if (maxlen > 0) { 
      var remaining = (maxlen - (parseInt($(element).val().replace(/(\r\n|\n|\r)/gm, '\r\n').length))); 
      if (remaining < 0) { 
       return false; 
      } 
     } 

     return true; 
    }); 

那麼這段代碼實際上確實是讓最大長度值,然後獲得然後它將所有「\ n」字符替換爲「\ r \ n」,以獲得與服務器相同的字符數。

2

我延長羅賓Ridderholt的解決方案,現在我們可以參考MAXLEN來驗證

$.validator.addMethod('extMaxLength', function (value, element, maxlen){ 
      if (maxlen > 0) { 
       var remaining = (maxlen - (parseInt($(element).val().replace(/(\r\n|\n|\r)/gm, '\n').length, 10))); 
       if (remaining < 0) { 
        return false; 
       } 
      } 
      return true; 
     }); 
0

我建議只是的Jakub Berezanski的解決方案的改進。

我個人發現他的想法(通常在服務器端處理這個問題)非常好。

只是他的示例代碼存在一個問題,那就是該模型在覆蓋BindProperty方法時最終已經失效 - 如果它是由我們正在糾正的那個字段的長度引起的。

因此,我改進建議他的解決方案是已經適用同樣的邏輯在GetPropertyValue覆蓋, - 這驗證之前執行:

public class NewlinesNormalizingModelBinder : DefaultModelBinder 
{ 
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) 
    { 
     // Note: if desired, one could restrict the conversion to properties decorated with [StringLength]: 
     // && propertyDescriptor.Attributes.OfType<StringLengthAttribute>().Any() 
     if (propertyDescriptor.PropertyType == typeof(string)) 
     { 
      string originalString = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue; 

      if (!string.IsNullOrEmpty(originalString)) return originalString.Replace("\r\n", "\n"); 
     } 

     return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); 
    } 
}