用于客户端表单验证和交互的最佳JavaScript解决方案? [英] Best JavaScript solution for client-side form validation and interaction?

查看:110
本文介绍了用于客户端表单验证和交互的最佳JavaScript解决方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的网页形式非常复杂。什么是可扩展表单验证的优秀解决方案,最好是可以与jQuery一起使用的解决方案?



背景:



我们的网站有一点Ajax,但真正关注的是用户体验,通过大约20个多页面表单或向导。这些表单很复杂。




  • 演示文稿:某些字段是浮动内容或整数。验证意味着剥离非十进制字符,但我们也希望确保,如果用户在价格字段中输入 5 ,字段将更新为 5.00

  • 副作用:更新时,某些字段有副作用。例如,更新商品的价格或数量需要更新小计字段。

  • 小工具驱动的元素:某些字段是隐藏的,并且由小工具填充值。例如,地图小部件可让您指向某个位置,并且隐藏字段将使用纬度 - 经度坐标进行更新,但位置必须位于特定区域内。 / strong>一些字段是组,例如地址/城市/州/邮政编码,并且只应在所有字段都被填充时验证。

  • 服务器端验证: 验证某些字段需要通过Ajax请求进行后端检查

  • 每页多个表单:有时,用户需要先填写一个表单对话框以另一种形式打开。框架必须比绑定 onSubmit 更通用 - 我们有时会使用Ajax按照从同一页开始的顺序发布多个表单。 (例如,我们允许用户一次注册并创建一个小部件,但由于遗留系统,该流需要两个POST请求。)
  • 可自定义的错误显示:
  • strong>有时候错误会出现在字段的上方,有时字段样式会发生变化,而我们的新设计需要类似于工具提示的弹出窗口(ala qTip )出现一些错误。 快乐:用户体验是关键,触觉反馈非常重要。任何解决方案
  • 提交按钮:单击提交按钮需要验证所有内容,然后显示响应 - 但由于某些验证是异步发生的。


我们目前使用 jQuery验证图书馆,但我们的形式似乎超出了它的能力。我一直在寻找诸如< angular /> Knockout Backbone.js ,但我担心它们太重或者它们会要求我们重写我们的前端。



(这应该是一个社区维基)。 是一个无耻的插件,但我可以自愿使用我设计的框架吗?我已经基于注释(一种Hibernate验证器)来构建它。它支持自定义约束,我觉得它非常强大。 这里也是一个Stackoverflow的问题,我问了一个关于框架。


  • 演示文稿:使用自定义验证约束,您可以将验证绑定到onChange元素。此外,由于Regula支持自定义验证器,因此您可以让自定义验证器更新字段的值(将 5 更改为 5.00
  • 副作用:Regula通过自定义约束验证程序支持副作用。

  • :Regula支持验证组。您可以定位特定组进行验证。通过组合一个自定义的验证器和一个组,你可以控制验证器的行为,以便它只在该组的所有元素都被填充时才验证(但你必须通过普通的Javascript来执行此检查) 。
  • 服务器端验证:使用自定义约束,您可以进行AJAX调用以执行服务器端验证。随着框架目前的结构化,这必然是一个拦截Ajax调用。我计划在将来添加一个异步功能。
  • :Regula不仅限于每页验证一个表单。它可以处理多种形式(不确定是否正确理解您的要求 - 所以我可能没有正确回答这个部分)。 可定制的错误显示: Regula doesn就验证而言,不会对页面的UI做任何事情。验证时,会得到一组包含错误消息等的约束违规。它取决于你,如何显示它们。
  • 快乐:我没有执行任何基准测试,所以我不能评论我的框架在这​​方面的表现关注。

  • 提交按钮:这是我还没有解决的问题(异步与同步)。


以下是一些示例:

以下显示了带有内置约束的标准验证:

 < input id =myInput
name =myInput
type =text
class = regula-validation
data-constraints ='@NotEmpty @IsNumeric @Between(min = 1,max = 5)'/>

jQuery(document).ready(function(){
// //必须首先调用regula.binnd()。最好的地方是在
// onload处理程序中。这个函数查找带有
//元素名称为regula-validation的元素,并将
//适当的约束绑定到元素

regula.bind();

jQuery(#myForm)。submit(function(){
//此函数执行实际验证
var validationResults = regula.validate();

for(var index in validationResults){
var validationResult = validationResults [index];
alert(validationResult.message);
}
});
});

正如您所看到的,您只是在处理约束违规问题,所以您的方式显示错误信息完全取决于您。



以下是自定义约束的示例:

  regula.custom({
name:MustBe42,
defaultMessage:答案必须等于42,
验证器:function(){
返回this.value == 42;
}
});

及其用途:

 < input id =theAnswerToLifeTheUniverseAndEverything
name =theAnswerToLifeTheUniverseAndEverything
value =
class =regula-validation
data-constraints =@ MustBe42/>

由于验证器是一个Javascript函数,因此您可以让它执行任何操作

以下是接受参数的另一个约束示例:

  regula.custom({
name:DivisibleBy,
defaultMessage:{label}必须可以被{divisor}整除,
params:[divisor],
validator:function(params){
var divisor = params [divisor];
return(this.value%divisor)== 0;
}
});



以及用法:

 < input id =number
name =number
value =
class =regula-validation
data-constraints = @DivisibleBy(divisor = 3,label ='The Number')/>

以下是使用验证组的示例:

 < input id =score
name =score
type =text
class =regula-validation
data-constraints ='@IsNumeric(label =Score,
message ={label}'需要是一个数字!'
groups = [FirstGroup,SecondGroup,ThirdGroup]'/> ;

< input id =age
name =age
type =text
class =regula-validation
data-constraints ='@IsNumeric(label =Age,
message ={label}必须是一个数字!
groups = [SecondGroup]'/>

< input id =name
name =name
type =text
class =regula-validation
data-constraints ='@NotEmpty (label =Name,
message ={label}不能为空!
groups = [FirstGroup]'/>

以及仅验证 FirstGroup 的片段所以只有得分名称被验证):

  var constraintViolations = regula.validate({groups:[regula.Group.FirstGroup]}); 
var messages =;

for(var index in constraintViolations){
var constraintViolation = constraintViolations [index];
messages + = constraintViolation.message +\\\
;


if(messages!=){
alert(messages);
}

如果您打算试用它,我建议您下载 1.1.1 即可。当前的文档特别与该版本匹配。在 1.2.1 中,我添加了对复合约束的支持,但我没有更新我的文档以反映这一点。



我明白这是不是没有解决你所有的疑虑,或者如果这不是你想要的。我以为我只是把它放在那里。另外,如果您确实检查了一下,我会确保更新文档以反映版本 1.2.1 。我一直忙于学校和工作,所以我没有时间这样做。



更新#1



Sohnee 提到客户端验证。我实际上正在研究Regula和Spring 3之间的整合。希望我能够在不久的将来发布它(取决于工作和学校)。该集成通过将Hibernate验证约束转换为Regula验证约束来实现。这样,你只需要一次(主要)编写验证代码。不过,对于自定义约束,您仍然必须在Javascript端编写代码(自定义验证器)。但是一旦你用Hibernate验证约束在服务器端注释代码,你就不需要在客户端做任何事情;这些约束自动应用于客户端的表单元素。



Matthew Abbott 也能够将Regula与ASP.NET MVC集成

更新#2



我有一个演示webapp(mavenized ) on github ,它展示了使用Hibernate Validator在Regula和Spring 3.0.x Web MVC之间的集成。它没有真正的文件或任何东西,这是更多的概念验证。我计划在github页面中添加一些关于集成和它如何工作的文档。

更新#3



我已经更新了 wiki 上的文档,现在对应于最新版本 1.2.2 (我做了一个小bug修复,这就是为什么它现在是 1.2.2 )。


Our web forms are really complex. What's a great solution for extensible form validation, preferably one that works with 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.

  • 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 to 5.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.

We're currently using the jQuery Validation library but our forms appear to be outgrowing its capability. I've been looking at things like <angular/>, Knockout and Backbone.js, but I'm worried that they're too heavyweight or that they would require us to rewrite our frontend.

(This should be a community wiki.)

解决方案

This is a shameless plug, but might I volunteer a framework that 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. Here is also a Stackoverflow question where I asked for a review of the framework.

  • 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 to 5.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 only when 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).

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

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

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.1 I added support for compound constraints, but I haven't updated my documentation to reflect that.

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.

UPDATE #1

Sohnee mentioned 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.

Matthew Abbott has also been able to integrate Regula with ASP.NET MVC.

UPDATE #2

I've got a demo webapp (mavenized) on github that 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.

UPDATE #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.2 now).

这篇关于用于客户端表单验证和交互的最佳JavaScript解决方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆