2010-12-03 15 views
13

Estoy usando jQuery.validate v 1.6.0 para validar mis formularios.jQuery validar error máximo de longitud de texto textarea

Uno de los campos de mi base de datos está limitado a 1000 caracteres. He añadido una validación para el área de texto correspondiente así:

En la cabecera de mi página, agrego

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

Dentro de mi página, declaro:

<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> 

El problema que estoy Encuentro es que jQuery parece contar el número de caracteres implicados en una 'nueva línea' de forma diferente a mi base de datos.

Cuando escribo exactamente 1000 caracteres sin líneas nuevas, todo va bien y la validación funciona. Si escribo 1000 caracteres con algunas líneas nuevas, jQuery permite que ocurra el POST, pero mi base de datos rechaza la inserción/actualización, porque los datos son demasiado grandes.

Cualquier sugerencia sería apreciada.

+0

estoy corriendo en este tema. ¡Realmente sorprendido de que más personas no se encuentren con esto! –

+0

También tenga en cuenta que el validador de jquery "recorta" el contenido, p. los espacios finales y las alimentaciones de línea no se cuentan – nuander

Respuesta

-5

Elimine la Validación del servidor y conserve solo la Validación del lado del cliente. En html nueva línea = 3 char En la base de datos nueva línea = 1 char Así que debe guardar solo una a la vez. o Cambie la configuración db char

+1

¿Validación del servidor de inserción? Debe ser una broma, ¿verdad? ¿Alguna vez has intentado algo tan simple como tamperdata? => solo la validación del cliente es una puerta abierta a todo tipo de piratería. – grootjans

+0

El único tipo de validación en la que puede confiar es en el servidor. Si debe eliminar cualquier validación, debe ser una validación del cliente. – Falle1234

2

Si bien esta no es una solución del lado del cliente, pude manejar el lado del servidor problemático.

Básicamente elimino los caracteres "adicionales" que son los caracteres "\ r". Supongo que estos no cuentan para la longitud de cadena en el navegador, o se combinan como uno con los caracteres "\ n".

En mi caso, ASP.NET MVC con 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... 
} 
+0

Excelente idea John! Un ajuste para mí - si usa un apporach de ViewModel: set {ModelName.Comment = value.Length> 0? value.Replace ("\ r", ""): string.Empty; } –

1

me encontré con el mismo tipo de problema. esto se debe al hecho de que en javascript, field.length devolvería la cantidad de caracteres, pero un personaje puede usar 2 bytes para almacenar información.

Mi problema es que un campo VARCHAR2 en la base de datos solo puede almacenar 4000Bytes de información, o 2000Characters. Nos confundimos fácilmente y creemos que podemos almacenar 4000 caracteres en este tipo de campos.

Creo que en su caso, el campo no está limitado a 1000chars, sino a 1000bytes, que pasan a ser lo mismo solo que usa "caracteres estándar" que usan un byte de información, así que recargo el límite a 2000Bytes y mantener la validación de javascript en 1000chars. Entonces, por supuesto, iría en contra de la respuesta anterior y haría una validación del lado del servidor sobre la cantidad de caracteres.

Por supuesto que tiene otras soluciones, en mi caso, por ejemplo (no estaba usando Jquery), modifiqué el contador de caracteres para contar dos veces cada carácter especial (estos problemas afectan a los caracteres nuevos, pero también a los acentos ... .)

1

También tomé el enfoque del lado del servidor, como hizo John Bubriski, pero lo implementé en ASP.NET MVC como una extensión de la DefaultModelBinder, por lo que todas las acciones del controlador se beneficiarán de inmediato:

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); 
      } 
     } 
    } 
} 

A continuación, en el inicio de la aplicación:

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

Si esto está ocurriendo sólo en el caso de la <textarea> continuación, por favor utilice el siguiente código:

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

Esto definitivamente funcionará.

+0

Esto no es una solución de validación jquery. – tjans

4

He cruzado este problema con jQuery Validate 1.9. Debido a que estoy usando ASP.NET MVC 3 y C# en el servidor, los saltos de línea eran "\ r \ n" en el servidor pero "\ n" en el cliente. Cuando validé mi área de texto en el cliente, la validación no falló porque "\ n" solo se cuenta como un carácter, pero cuando el texto pasó a la validación en el servidor donde los saltos de línea son "\ r \ n" la validación fallaría.

Mi soultion a este problema fue la de anular jQuery método de validación "rangelengt" porque también tengo una longitud mínima definida:

$.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; 
    }); 

Entonces, ¿este código en realidad no es para obtener el valor maxlength y luego obtener el valor del elemento y luego reemplaza todos los caracteres "\ n" con "\ r \ n" para obtener el mismo número de caracteres que el servidor.

2

que se extienden solución Robin Ridderholt, ahora podemos referirnos maxlen al validador

$.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

me gustaría sugerir simplemente una mejora de la solución Jakub Berezanski 's.

Personalmente encuentro su idea (de manejar esto generalmente en el lado del servidor) muy buena.

Un solo problema con su código de ejemplo podría ser que el modelo ya no es válido en el momento de anular el método BindProperty, si es causado solo por la longitud del campo que estamos corrigiendo allí.

Por lo tanto, mi sugerencia de mejora a su solución es aplicar la misma lógica que ya están en la anulación GetPropertyValue, - que se ejecuta antes de la validación:

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); 
    } 
}