客户端表单验证和交互的最佳 JavaScript 解决方案?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4751780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best JavaScript solution for client-side form validation and interaction?
提问by a paid nerd
Our web forms are really complex. What's a great solution for extensible form validation, preferably one that works with jQuery?
我们的网络表单非常复杂。什么是可扩展表单验证的好解决方案,最好是与 jQuery 一起使用的解决方案?
Background:
背景:
Our site has a bit of Ajax, but the real focus is on user experience through about 20 multi-page forms or "wizards." These forms are complicated.
我们的网站有一些 Ajax,但真正的重点是通过大约 20 个多页面表单或“向导”来实现用户体验。这些表格很复杂。
- Presentation:Some fields are floats or ints. Validation means stripping non-decimal characters, but we also want to make sure that, if a user enters
5
into a price field, the field is updated to5.00
. - Side effects:Some fields have side effects when updated. E.g., updating the price or quantity of an item needs to update a subtotal field.
- Widget-driven elements:Some fields are hidden and have values populated by widgets. E.g., a map widget lets you point to a location and a hidden field is updated with latitude-longitude coordinates, but the location must be within a certain region.
- Groups:Some fields are groups, like address/city/state/zip, and should only be validated when all of the fields have bee populated.
- Server-side validation:Validation of some fields requires back-end checking via Ajax requests
- Multiple forms per page:Sometimes a user needs to fill out one form before a dialog opens with another form. A framework has to be more versatile than binding to
onSubmit
— we sometimes post multiple forms in order from the same page using Ajax. (E.g., we let users sign up and create a widget in one swoop but, due to legacy systems, that flow requires two POST requests.) - Customizable error display:Sometimes errors appear above fields, sometimes the field style changes, and our new designs call for tooltip-like popups (ala qTip) for some errors.
- Snappiness:User experience is key and tactile feedback is important. Any solution
- Submit buttons:Clicking the submit button needs to validate everything and then show a response — but since some of the validation happens asynchronously.
- 介绍:一些字段是浮点数或整数。验证意味着去除非十进制字符,但我们还希望确保,如果用户输入
5
价格字段,该字段将更新为5.00
。 - 副作用:某些字段在更新时会产生副作用。例如,更新商品的价格或数量需要更新小计字段。
- 小部件驱动的元素:某些字段是隐藏的,并且具有由小部件填充的值。例如,地图小部件可让您指向某个位置,并且使用经纬度坐标更新隐藏字段,但该位置必须在某个区域内。
- 组:某些字段是组,例如地址/城市/州/邮编,并且仅应在填充所有字段时进行验证。
- 服务器端验证:某些字段的验证需要通过 Ajax 请求进行后端检查
- 每页多个表单:有时用户需要填写一个表单,然后用另一个表单打开对话框。框架必须比绑定更通用
onSubmit
——我们有时使用 Ajax 从同一页面按顺序发布多个表单。(例如,我们让用户一次性注册并创建一个小部件,但由于遗留系统,该流程需要两个 POST 请求。) - 可定制的错误显示:有时错误会出现在字段上方,有时字段样式会发生变化,我们的新设计会为某些错误调用类似工具提示的弹出窗口 (ala qTip)。
- Snappiness:用户体验是关键,触觉反馈很重要。任何解决方案
- 提交按钮:单击提交按钮需要验证所有内容,然后显示响应——但由于某些验证是异步发生的。
We're currently using the jQuery Validationlibrary but our forms appear to be outgrowing its capability. I've been looking at things like <angular/>, Knockoutand Backbone.js, but I'm worried that they're too heavyweight or that they would require us to rewrite our frontend.
我们目前正在使用jQuery 验证库,但我们的表单似乎超出了它的能力。我一直在研究诸如<angular/>、Knockout和Backbone.js 之类的东西,但我担心它们太重量级或者它们需要我们重写我们的前端。
(This should be a community wiki.)
(这应该是一个社区维基。)
回答by Vivin Paliath
This is a shameless plug, but might I volunteer a frameworkthat I designed? I've built it based on annotations (a la Hibernate Validator). It has support for custom constraints and I feel that it is pretty powerful. Hereis also a Stackoverflow question where I asked for a review of the framework.
这是一个无耻的插件,但我可以自愿提供一个我设计的框架吗?我已经基于注释(a la Hibernate Validator)构建了它。它支持自定义约束,我觉得它非常强大。这也是一个 Stackoverflow 问题,我要求对框架进行。
- Presentation: With custom validation-constraints, you can bind validation to the onChange element. Also, because Regula supports custom validators, you can have your custom validator update the value of a field (so change
5
to5.00
). - Side effects: Regula supports side-effects via custom constraint-validators.
- Groups: Regula supports validation groups. You can target specific groups for validation. By combining a custom validator and a group, you can control the behavior of the validator so that it validates onlywhen all elements of that group are filled (you would have to perform this check via normal Javascript though).
- Server-side validation: With custom-constraints, you can make an AJAX call to perform server-side validation. With the way the framework is structured currently, this necessarily has to be a blocking ajax-call. I plan on adding an asynchronous feature in the future.
- Multiplee forms per page: Regula isn't limited to validating one form per page. It can handle multiple forms (not sure if I understood your requirement correctly - so I might not have answered this part correctly).
- Customizable error display:Regula doesn't do anything to the UI of the page as far as validation is concerned. When you validate, you get a set of constraint violations that contain error messages and such. It is up to you, how to display them.
- Snappiness:I haven't performed any benchmarks, so I cannot comment as to my framework's performance in this regard.
- Submit buttons:This is something I have yet to solve (asynchronous vs. synchronous).
- 演示:使用自定义验证约束,您可以将验证绑定到 onChange 元素。此外,由于 Regula 支持自定义验证器,您可以让自定义验证器更新字段的值(因此更改
5
为5.00
)。 - 副作用:Regula 通过自定义约束验证器支持副作用。
- 组:Regula 支持验证组。您可以针对特定组进行验证。通过组合自定义验证器和组,您可以控制验证器的行为,以便仅在填充该组的所有元素时才进行验证(尽管您必须通过普通 Javascript 执行此检查)。
- 服务器端验证:使用自定义约束,您可以进行 AJAX 调用以执行服务器端验证。根据当前框架的结构方式,这必然是一个阻塞的 ajax 调用。我计划在未来添加异步功能。
- 每页多个表单:Regula 不限于每页验证一个表单。它可以处理多种形式(不确定我是否正确理解您的要求 - 所以我可能没有正确回答这部分)。
- 可定制的错误显示:就验证而言,Regula 不对页面的 UI 做任何事情。验证时,您会得到一组包含错误消息等的约束违规。如何显示它们取决于您。
- Snappiness:我没有执行任何基准测试,所以我无法评论我的框架在这方面的表现。
- 提交按钮:这是我尚未解决的问题(异步与同步)。
Here are a few examples:
这里有一些例子:
The following shows standard validation, with built-in constraints:
下面显示了带有内置约束的标准验证:
<input id = "myInput"
name = "myInput"
type = "text"
class = "regula-validation"
data-constraints = '@NotEmpty @IsNumeric @Between(min=1, max=5)' />
jQuery(document).ready(function() {
// must call regula.binnd() first. The best place would be in an
// onload handler. This function looks for elements with
// a class name of "regula-validation" and binds the
// appropriate constraints to the elements
regula.bind();
jQuery("#myForm").submit(function() {
// this function performs the actual validation
var validationResults = regula.validate();
for(var index in validationResults) {
var validationResult = validationResults[index];
alert(validationResult.message);
}
});
});
As you can see, you're only working with constraint violations, and so the manner in which you display the error message is entirely up to you.
如您所见,您只处理违反约束的情况,因此显示错误消息的方式完全取决于您。
Here's an example of a custom constraint:
这是自定义约束的示例:
regula.custom({
name: "MustBe42",
defaultMessage: "The answer must be equal to 42",
validator: function() {
return this.value == 42;
}
});
And its use:
及其用途:
<input id = "theAnswerToLifeTheUniverseAndEverything"
name = "theAnswerToLifeTheUniverseAndEverything"
value = ""
class = "regula-validation"
data-constraints = "@MustBe42" />
Since the validator is a Javascript function, you can have it do anything (so this addresses your question about side effects).
由于验证器是一个 Javascript 函数,你可以让它做任何事情(所以这解决了你关于副作用的问题)。
Here is an example of another constraint that accepts parameters:
这是接受参数的另一个约束的示例:
regula.custom({
name: "DivisibleBy",
defaultMessage: "{label} must be divisible by {divisor}",
params: ["divisor"],
validator: function(params) {
var divisor = params["divisor"];
return (this.value % divisor) == 0;
}
});
And usage:
和用法:
<input id = "number"
name = "number"
value = ""
class = "regula-validation"
data-constraints = "@DivisibleBy(divisor=3, label='The Number')" />
Here is an example of using validation groups:
以下是使用验证组的示例:
<input id = "score"
name = "score"
type = "text"
class = "regula-validation"
data-constraints = '@IsNumeric(label="Score",
message="{label} needs to be a number!"
groups=[FirstGroup, SecondGroup, ThirdGroup]' />
<input id = "age"
name = "age"
type = "text"
class = "regula-validation"
data-constraints = '@IsNumeric(label="Age",
message="{label} needs to be a number!"
groups=[SecondGroup]' />
<input id = "name"
name = "name"
type = "text"
class = "regula-validation"
data-constraints = '@NotEmpty(label="Name",
message="{label} cannot be empty!"
groups=[FirstGroup]' />
And a snippet that validates only FirstGroup
(so only score
and name
are validated):
以及仅验证的代码段FirstGroup
(仅验证score
并name
验证):
var constraintViolations = regula.validate({groups: [regula.Group.FirstGroup]});
var messages = "";
for(var index in constraintViolations) {
var constraintViolation = constraintViolations[index];
messages += constraintViolation.message + "\n";
}
if(messages != "") {
alert(messages);
}
If you're planning on trying it out, I recommend downloading version 1.1.1. The current documentation matches that version specifically. In 1.2.1I added support for compound constraints, but I haven't updated my documentation to reflect that.
如果您打算尝试一下,我建议您下载1.1.1版。当前文档特别匹配该版本。在1.2.1 中,我添加了对复合约束的支持,但我没有更新我的文档来反映这一点。
I understand if this doesn't address all your concerns, or if this is not what you are looking for. I thought I'd just put it out there. Also, if you do check it out then I will make sure to update the documentation to reflect version 1.2.1. I've been busy with school and work and so I haven't had the time to do that.
我理解这是否不能解决您的所有问题,或者这不是您想要的。我以为我只是把它放在那里。另外,如果您确实检查了它,那么我将确保更新文档以反映版本1.2.1。我一直忙于学校和工作,所以我没有时间去做。
UPDATE #1
更新 #1
Sohneementioned client-side validation. I'm actually working on an integration between Regula and Spring 3. Hopefully I should be able to release it sometime soon (depending again, on work and school). The integration works by translating Hibernate validation-constraints to Regula validation-constraints. This way, you only have to write validation code once (mostly). For custom constraints though, you will still have to write code on the Javascript side (the custom validator). But once you annotate code on the server-side with Hibernate validation-constraints, you don't need to do anything on the client-side; those constraints automatically get applied to form elements on the client-side.
Sohnee提到了客户端验证。我实际上正在研究 Regula 和 Spring 3 之间的集成。希望我能很快发布它(再次取决于工作和学校)。集成通过将 Hibernate 验证约束转换为 Regula 验证约束来工作。这样,您只需编写一次验证代码(大多数情况下)。但是对于自定义约束,您仍然需要在 Javascript 端(自定义验证器)编写代码。但是一旦您使用 Hibernate 验证约束在服务器端注释代码,您就不需要在客户端做任何事情;这些约束会自动应用于客户端的表单元素。
Matthew Abbotthas also been able to integrate Regula with ASP.NET MVC.
Matthew Abbott还能够将 Regula 与 ASP.NET MVC 集成。
UPDATE #2
更新 #2
I've got a demo webapp (mavenized) on githubthat showcases the integration between Regula and Spring 3.0.x Web MVC using Hibernate Validator. It's not really documented or anything, it's more proof-of-concept. I plan to add some documentation to the github page about the integration and how it works.
我在 github 上有一个演示 webapp(mavenized),它展示了 Regula 和 Spring 3.0.x Web MVC 之间使用 Hibernate Validator 的集成。它没有真正记录或任何东西,它更像是概念证明。我计划向 github 页面添加一些关于集成及其工作原理的文档。
UPDATE #3
更新 #3
I've updated the documentation on the wiki, and it now corresponds to the latest version, 1.2.2(I made a little bugfix, which is why it is 1.2.2now).
我已经更新了wiki上的文档,它现在对应于最新版本1.2.2(我做了一个小错误修正,这就是它现在是1.2.2 的原因)。
回答by Mitch Malone
I have used this jQuery formValidatorseveral times in conjunction with a whole bunch of different environments. I hope it helps as I've rarely spent more than an hour setting it up.
我已经多次将这个jQuery formValidator与一大堆不同的环境结合使用。我希望它有所帮助,因为我很少花一个多小时来设置它。
Cheers!
干杯!
回答by Tracker1
I would say the jQuery Validationplugin does a good job. I have it combined with the metadataplugin to pass the server-side validation parameters to the client. I've also wrapped a few key points to all forms so that I can use a common pattern for validation, and a few exceptional/custom states. This includes a custom alert message and display.
我会说jQuery 验证插件做得很好。我将它与元数据插件结合起来将服务器端验证参数传递给客户端。我还为所有表单包装了一些关键点,以便我可以使用通用模式进行验证,以及一些特殊/自定义状态。这包括自定义警报消息和显示。
It does not do everything you want out of the box, but it is the best option and the best default behavior I've seen. Again, I do use the metadata (attribute "data-meta") with it. And it can be bent to your will. I'm also using metadata for control binding to input elements client-side. This splits my client-side logic from server-side, but easier in the long run over trying to inject js from the server-side logic.
它并没有开箱即用地完成您想要的一切,但它是我见过的最佳选择和最佳默认行为。同样,我确实使用了元数据(属性“data-meta”)。它可以随你的意愿弯曲。我还使用元数据来控制绑定到客户端的输入元素。这将我的客户端逻辑与服务器端分开,但从长远来看,尝试从服务器端逻辑注入 js 更容易。
回答by Simone
Parsley.jslooks to be a nice and popular choice at time of writing (august 2013).
在撰写本文时(2013 年 8 月),Parsley.js看起来是一个不错且受欢迎的选择。
回答by a paid nerd
Answering this myself since someone on our team noticed Validator from jQuery Tools!
我自己回答这个问题,因为我们团队中有人注意到jQuery Tools 中的 Validator!
- Presentation- Supports HTML5 input fields.
pattern
fields make sure the user can only input test in a certain pattern. - Side effects- Triggers events on the form and on individual fields:
onFail
andonSuccess
- Widget-driven elements- "Custom input types" are encouraged. The basic demo even includes a natural numbers-old "age" field.
- Groups- Write a "function matcher" whose sole purpose is to filter which fields are to be validated.
- Server-side validation- Does it and does it intelligently — depends on your validator calling a callback (so it's async-friendly) instead of a return value.
- Multiple forms per page- jQuery Tools seems to be very well built and this shouldn't be a problem.
- Customizable error display- Errors next to fields? All in one place? No problem. Still not good enough? Bind events on failure. Even uses tooltips by default.
- Snappiness- Demos are very snappy
- Submit buttons- No problem.
- 演示文稿- 支持 HTML5 输入字段。
pattern
字段确保用户只能以某种模式输入测试。 - 副作用- 在表单和单个字段上触发事件:
onFail
和onSuccess
- 小部件驱动的元素- 鼓励“自定义输入类型”。基本演示甚至包括一个自然数旧的“年龄”字段。
- 组- 编写一个“函数匹配器”,其唯一目的是过滤要验证的字段。
- 服务器端验证- 执行并智能执行 - 取决于您的验证器调用回调(因此它是异步友好的)而不是返回值。
- 每页多个表单- jQuery 工具似乎构建得非常好,这应该不是问题。
- 可定制的错误显示- 字段旁边的错误?都在一处?没问题。还是不够好?失败时绑定事件。甚至默认使用工具提示。
- 活泼- 演示非常活泼
- 提交按钮- 没问题。
Update:Yep, just reimplemented a chunk of our site with jQuery Tools' validator tooltips. Fantastic!
更新:是的,刚刚使用 jQuery Tools 的验证器工具提示重新实现了我们网站的一部分。极好的!
回答by Fenton
Server-side validation rocks.
服务器端验证岩石。
Supply the results of such validation via an AJAX request if you like... or use a server-side framework that will also add client-side validation - but don't write it twice.
如果您愿意,可以通过 AJAX 请求提供此类验证的结果……或者使用服务器端框架也将添加客户端验证——但不要重复编写。
回答by Hello Universe
Go with jQuery Validation plugins. It never failed me so far
使用 jQuery 验证插件。到目前为止它从来没有让我失望过
回答by Sushant Patil
function isEmpty(text) {
if(text == undefined) {
return true;
}
if(text.replace(/\s+/g, ' ').length == 0) {
return true;
}
return false;
}
function isValidBoolean(text) {
if(text == undefined || (text.toLowerCase() != "true" && text.toLowerCase() != "false")) {
return false;
}
return true;
}
function isValidDouble(text) {
var out = parseFloat(text);
if(isNaN(out)) {
return false;
}
return true;
}
function isValidLong(text) {
var out = parseInt(text);
if(isNaN(out)) {
return false;
}
return true;
}
function isValidDate(text) {
if(Date.parseString(text, 'MM/dd/yyyy HH:mm:ss') == null) {
return false;
}
return true;
}
function hasDuplicates(array) {
var valuesSoFar = {};
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (Object.prototype.hasOwnProperty.call(valuesSoFar, value)) {
return true;
}
valuesSoFar[value] = true;
}
return false;
}