Javascript 表单验证(角度)
我使用的是角度反应形式和距离输入字段,它有两个输入框,分别称为Javascript 表单验证(角度),javascript,angular,typescript,validation,angular-reactive-forms,Javascript,Angular,Typescript,Validation,Angular Reactive Forms,我使用的是角度反应形式和距离输入字段,它有两个输入框,分别称为From和To HTML: <form [formGroup]="form"> <button (click)="addRow()">Add</button> <div formArrayName="distance"> <div *ngFor="let item of form.get('distance').controls; let i = ind
From
和To
HTML:
<form [formGroup]="form">
<button (click)="addRow()">Add</button>
<div formArrayName="distance">
<div
*ngFor="let item of form.get('distance').controls; let i = index"
[formGroupName]="i"
style="display: flex"
>
<input type="number" placeholder="From" formControlName="from" />
<div><input type="number" placeholder="To" formControlName="to" /></div>
</div>
</div>
<br /><br />
<button type="submit" [disabled]="!form.valid">Submit</button>
</form>
ngOnInit() {
this.form = this.fb.group({
distance: this.fb.array([]),
});
this.addRow()
}
addRow() {
const control = this.form.controls.distance as FormArray;
control.push(this.fb.group({
from: ['',Validators.required],
to: ['',Validators.required]
}));
}
在这里,您可以看到默认情况下的两个输入框,分别为from
和to
顶部有一个“添加”按钮,单击“添加”按钮后,将添加具有相同输入字段的行,并形成数组
这里我需要限制用户不允许输入前一行到值,也不允许小于该值的值
例如
在第一行中,如果用户分别为from和to输入以下值,如0和5
"distance": [
{
"from": 0,
"to": 5
}
]
单击“添加”后,用户需要限制在输入框的第二行中添加小于等于5的值(这意味着这些值已经输入)
所以这样是无效的,
{
"distance": [
{
"from": 0,
"to": 5
},
{
"from": 5,
"to": 10
}
]
}
此处“from”:5、
或“from”:4(或)3(或)2(或)1
,第二行中的任何内容均无效
只有6和大于6才有效
同样,对于每一行,它需要检查前一行的值,并且需要进行验证
请帮助我实现这种类型的验证,即限制用户不输入上一行的值(或)小于当前行的from值
工作示例:
编辑:
<form [formGroup]="form">
<button (click)="addRow()">Add</button>
<div formArrayName="distance">
<div
*ngFor="let item of form.get('distance').controls; let i = index"
[formGroupName]="i"
style="display: flex"
>
<input type="number" placeholder="From" formControlName="from" />
<div><input type="number" placeholder="To" formControlName="to" /></div>
</div>
</div>
<br /><br />
<button type="submit" [disabled]="!form.valid">Submit</button>
</form>
ngOnInit() {
this.form = this.fb.group({
distance: this.fb.array([]),
});
this.addRow()
}
addRow() {
const control = this.form.controls.distance as FormArray;
control.push(this.fb.group({
from: ['',Validators.required],
to: ['',Validators.required]
}));
}
尝试输入更改,例如
<input type="number" (input)="onInputChange($event.target.value)" placeholder="From" formControlName="from">
在链接中,但不确定我是否正确
如果此过程错误,请进行更改。只需使用customValidation(我在同一组件中选择验证)
ngOnInit() {
this.form = this.fb.group({
distance: this.fb.array([], this.distanceValidator()),
});
this.addRow()
}
distanceValidator() {
return (fa: FormArray) => {
let ok = true;
let ok2 = fa.value.length ? (!fa.value[0].to || !fa.value[0].from) || fa.value[0].to > fa.value[0].from : true;
if (!ok2)
return { error: "from greater than to" }
for (let i = 1; i < fa.value.length; i++) {
if (fa.value[i].from && fa.value[i].to )
{
ok = (fa.value[i].from > fa.value[i - 1].to || fa.value[i].to < fa.value[i - 1].from);
ok2 = (fa.value[i].to > fa.value[i].from);
if (!ok)
return { error: "from/to yet included" }
if (!ok2)
return { error: "from greater than to" }
}
}
return ok && ok2 ? null : !ok?{ error: "from yet included" }:{ error: "from greater than to" }
}
}
ngOnInit(){
this.form=this.fb.group({
距离:this.fb.array([],this.distanceValidator()),
});
this.addRow()
}
距离验证器(){
返回(fa:FormArray)=>{
让ok=true;
设ok2=fa.value.length(!fa.value[0]。to | | |!fa.value[0]。from)| | fa.value[0]。to>fa.value[0]。from:true;
如果(!ok2)
返回{error:“从大于到”}
for(设i=1;ifa.value[i-1]。to | | fa.value[i]。tofa.value[i].from);
如果(!ok)
返回{错误:“从/到尚未包含”}
如果(!ok2)
返回{error:“从大于到”}
}
}
返回ok&&ok2?null:!ok?{error:“从尚未包含”}:{error:“从大于到”}
}
}
你可以像其他人一样看到错误
<div *ngIf="form.get('distance')?.errors">
{{form.get('distance')?.errors.error}}
</div>
{{form.get('distance')?.errors.error}
参见[stackblitz forked][1]最后我决定将这两个条件分开。参见 (参见+fa.value[i-1]中的“+”。到和+fa.value[i-1]。从 好的,当我们决定发送错误时,假设您有6行,位置0、位置3和位置4(0是第一行)的行发送错误,如
{error:"there are errors",indexError:",0,3,4,"}
这允许在*NGF中写入类似的内容
<span *ngIf="form.get('distance')?.errors &&
form.get('distance')?.errors.indexError.indexOf(','+i+',')>=0">
**
</span>
**
我们的距离验证器变成了
distanceValidator() {
return (fa: FormArray) => {
let indexError:string="";
for (let i = 1; i < fa.value.length; i++) {
let ok = (!fa.value[i].from || fa.value[i].from > +fa.value[i - 1].to) && (!fa.value[i].to || fa.value[i].to > +fa.value[i - 1].from);
if (!ok)
indexError+=','+i;
}
return indexError?{error:"there are errors",indexError:indexError+','}:null
}
distanceValidator(){
返回(fa:FormArray)=>{
let indexer:string=“”;
for(设i=1;i+fa.value[i-1]。to)&(!fa.value[i]。to | | fa.value[i]。to>+fa.value[i-1]。from);
如果(!ok)
索引器+=','+i;
}
返回索引器?{错误:“有错误”,索引器:索引器+',}:空
}
有人可能会认为最好返回一个错误数组,但这是不允许的,因为我们不能简单地知道有错误的行。有些类似于errors.find(x=>x.id==i)不起作用,因为我们不能在插值中使用find
的确,只将一行与中间部分进行比较是正确的。在使用for(让j=i-1;j>0;j++){ok=ok&&&…}之前,可以检查所有行,但我认为这不是必需的,而且我们必须在代码上小气。请记住,函数distanceValidator会执行多次
请参阅另一个谢谢亲爱的Eliseo,错误消息未显示..我们如何按照您的示例显示错误消息?您可以显示错误“从大于到”,创建组的自定义验证程序(并将distanceValidator更改为简化)Eliseo还请更新您提供的stackblitz错误消息。再次感谢您的时间和帮助。如果我需要帮助,将返回给您。请重新检查stackblitz,如果我输入了错误的值,我无法获得错误消息。在“发件人”框中,错误消息未显示。请检查它。对于输入框its显示..欢迎使用您的新解决方案..但您正在单击设置默认按钮,其中第一行的值为0和5,第二行的值为6和2..但我看不到显示任何错误消息..您认为第二行的2是有效输入吗?请参见*和**不要着急Eliseo,我知道您的解决方案,因此我仍然是ex期待您提供一个好的解决方案请给我一个我需要的好的解决方案,并为每个解决方案显示正确的错误消息我将给您投票支持此解决方案如果您编辑此解决方案并显示正确的错误消息,我将接受此新解决方案请理解我需要什么Eliseo Eliseo另一个问题related关于这个问题,我需要根据旅行距离计算车费,请看上面的问题Eliseo,我真的需要你的帮助,请。。
<div *ngIf="form.get('distance')?.errors">
{{form.get('distance')?.errors.error}}
</div>