JQuery проверить ошибку textarea maxlength
Я использую jQuery.validate v 1.6.0 для проверки моих форм.
Одно из моих полей базы данных ограничено 1000 символами. Я добавил подтверждение в соответствующую текстовую область следующим образом:
В заголовке моей страницы я добавляю
$('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, но моя база данных отказывается от вставки/обновления, потому что данные слишком большие.
Любые подсказки будут оценены.
Ответы
Ответ 1
Я столкнулся с этой проблемой, используя jQuery Validate 1.9. Поскольку я использую ASP.NET MVC 3 и С# на разрыве строки сервера, это "\ r\n" на сервере, но "\n" на клиенте. Когда я подтвердил свое текстовое поле на клиенте, проверка не завершилась неудачей, потому что "\n" считается только одним символом, но когда текст перешел к проверке на сервере, где строки являются "\ r\n" , проверка не удалась.
Мое отношение к этой проблеме состояло в том, чтобы переопределить метод проверки 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;
});
Итак, что этот код на самом деле делает, это получить значение maxlength, а затем получить значение из этого элемента, а затем заменить все символы "\n" на "\ r\n" , чтобы получить одинаковое количество символов, чем сервер будет.
Ответ 2
Хотя это не клиентское решение, мне удалось обработать серверную проблему.
Я в основном выделяю "лишние" символы, которые являются символами "\ r". Я думаю, что они не учитывают длину строки в браузере или объединяются как с символами "\n".
В моем случае ASP.NET MVC с С#:
[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...
}
Ответ 3
Я расширяю решение Robin 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;
});
Ответ 4
Я столкнулся с такой же проблемой. это связано с тем, что в javascript field.length возвращает количество символов, но один символ может использовать 2 байта для хранения информации.
Моя проблема заключалась в том, что поле VARCHAR2 в БД может хранить только 4000 бит информации или 2000 символов.
Мы легко смущаемся и думаем, что можем хранить 4000 символов в таких полях.
Я думаю, что в вашем случае это поле не ограничивается 1000chars, но 1000 байт, которые, как оказалось, будут одинаковыми, вы используете только "стандартные символы", которые используют один байт информации, поэтому я бы восстановил предел до 2000 бит и сохраните проверку javascript до 1000chars.
Тогда, конечно, я бы пошел против предыдущего ответа и проверил проверку на стороне сервера на количество символов.
Конечно, у вас есть другие решения, например, в моем случае (я не использовал JQuery), я настраивал счетчик персонажей, чтобы считать дважды каждого специального символа (эти проблемы влияют на символы новой строки, но также и акценты.... )
Ответ 5
Я также использовал подход на стороне сервера, как это сделал Джон Бубриски, но реализовал его в ASP.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);
}
}
}
}
Затем при запуске приложения:
ModelBinders.Binders.DefaultBinder = new NewlinesNormalizingModelBinder();
Ответ 6
Я бы предложил только улучшение решения Якуба Березанского.
Я лично считаю, что его идея (обработка этого вообще на стороне сервера) очень хорошая.
Только одна проблема с его примером кода может заключаться в том, что в конечном итоге модель уже недействительна во время переопределения метода 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);
}
}
Ответ 7
Если это происходит только в случае <textarea>
, то используйте следующий код:
$(document).ready(function () {
$("input[type=submit]").live("click", function (e) {
if ($(textarea).val().length > 1000) {
e.preventDefault();
return false;
}
});
});
Это определенно будет работать.
Ответ 8
Откажитесь от проверки сервера и сохраните только проверку на стороне клиента.
В html новая строка = 3 char
В базе данных новая строка = 1 char
Так что вам нужно держать только один.
или Изменить настройку db char