将复选框控件与文本框控件相关联的最佳方式
Best way to associate checkbox control with textbox control
我一直在尝试许多不同的方法,但整个星期都失败了,我需要能够将复选框控件与答案相关联。
差不多,如果复选框被选中,那么用户必须回答问题并且它必须具有最小长度 4 的验证。
复选框将包含问题和答案。
因此,如果用户选择该问题,he/she 必须提供答案。
问题是从服务器在对象中呈现的,例如;
{
question_id: "1",
selected: true,
EN: "Question 1 - EN",
FR: "Question 1 -FR",
},
{
question_id: "2",
selected: false,
EN: "Question 2 - EN",
FR: "Question 2 -FR"
}
如果需要,我可以post我的代码,但是它很长很复杂。
如果您创建 Reactive Form 您可以动态更改验证
组件
this.questionForm = fb.group({
questions: fb.array(this.questions.map(this.createQuestionControl(fb)))
});
createQuestionControl(fb: FormBuilder) {
return (question, index) => {
const checkbox = question.selected
const answerbox = question.selected ? ['', [Validators.required, Validators.minLength(4)]] : ''
return fb.group({question: checkbox, answer: answerbox, questionNumber: index + 1});
}
}
changeValidator(selected, index) {
const answerbox = this.questionForm.get('questions.' + index).get('answer')
const validators = selected ? [Validators.required, Validators.minLength(4)] : null
answerbox.setValidators(validators);
answerbox.updateValueAndValidity();
}
createQuestionControl()
方法会将每个问题变成一个控件,如下所示,表单生成器可以将其变成一个包含问题和答案的组
{ question: true, answer: ['', [Validators.required, Validators.minLength(4)]], index: 4 }
如果问题发生变化,changeValidator()
方法将在答案上添加或删除验证器(注意:不要忘记 updateValueAndValidity
)
模板
<form [formGroup]="questionForm" (ngSubmit)="submit(questionForm)">
<div formArrayName="questions">
<div *ngFor="let question of questionForm.get('questions').controls | orderBySelected; let i = index;" [formGroupName]="i">
<!--{{questionForm.get('questions.' + i + '.questionNumber').value}}-->
{{questions[questionForm.get('questions.' + i + '.questionNumber').value - 1]['EN']}}
<input type="checkbox" formControlName="question" (ngModelChange)="changeValidator($event, i)"/>
<input type="text" formControlName="answer" />
<em *ngIf="questionForm.get('questions.' + i + '.answer').invalid">Minimum length 4</em>
</div>
</div>
<button type="submit" [disabled]="questionForm.invalid">Submit</button>
</form>
根据评论中的说明:
Maximum of 5 can be checked at a given time
我已将数组更新为具有不超过 3 的交叉字段验证(更容易测试,您可以将其更改为 5)
export function max3Selected(formArray) {
let totalSelected = formArray.controls.reduce((selectedControls, control) =>
{
if (control.get('question').value) {
selectedControls++
}
return selectedControls;
}, 0)
return totalSelected > 3 ? { moreThanThreeSelected: true } : null;
}
并且您将更改 fb.array
以包含验证器函数
fb.array(this.questions.map(this.createQuestionControl(fb)), max3Selected)
结果截图
我一直在尝试许多不同的方法,但整个星期都失败了,我需要能够将复选框控件与答案相关联。
差不多,如果复选框被选中,那么用户必须回答问题并且它必须具有最小长度 4 的验证。
复选框将包含问题和答案。
因此,如果用户选择该问题,he/she 必须提供答案。
问题是从服务器在对象中呈现的,例如;
{
question_id: "1",
selected: true,
EN: "Question 1 - EN",
FR: "Question 1 -FR",
},
{
question_id: "2",
selected: false,
EN: "Question 2 - EN",
FR: "Question 2 -FR"
}
如果需要,我可以post我的代码,但是它很长很复杂。
如果您创建 Reactive Form 您可以动态更改验证
组件
this.questionForm = fb.group({
questions: fb.array(this.questions.map(this.createQuestionControl(fb)))
});
createQuestionControl(fb: FormBuilder) {
return (question, index) => {
const checkbox = question.selected
const answerbox = question.selected ? ['', [Validators.required, Validators.minLength(4)]] : ''
return fb.group({question: checkbox, answer: answerbox, questionNumber: index + 1});
}
}
changeValidator(selected, index) {
const answerbox = this.questionForm.get('questions.' + index).get('answer')
const validators = selected ? [Validators.required, Validators.minLength(4)] : null
answerbox.setValidators(validators);
answerbox.updateValueAndValidity();
}
createQuestionControl()
方法会将每个问题变成一个控件,如下所示,表单生成器可以将其变成一个包含问题和答案的组
{ question: true, answer: ['', [Validators.required, Validators.minLength(4)]], index: 4 }
如果问题发生变化,changeValidator()
方法将在答案上添加或删除验证器(注意:不要忘记 updateValueAndValidity
)
模板
<form [formGroup]="questionForm" (ngSubmit)="submit(questionForm)">
<div formArrayName="questions">
<div *ngFor="let question of questionForm.get('questions').controls | orderBySelected; let i = index;" [formGroupName]="i">
<!--{{questionForm.get('questions.' + i + '.questionNumber').value}}-->
{{questions[questionForm.get('questions.' + i + '.questionNumber').value - 1]['EN']}}
<input type="checkbox" formControlName="question" (ngModelChange)="changeValidator($event, i)"/>
<input type="text" formControlName="answer" />
<em *ngIf="questionForm.get('questions.' + i + '.answer').invalid">Minimum length 4</em>
</div>
</div>
<button type="submit" [disabled]="questionForm.invalid">Submit</button>
</form>
根据评论中的说明:
Maximum of 5 can be checked at a given time
我已将数组更新为具有不超过 3 的交叉字段验证(更容易测试,您可以将其更改为 5)
export function max3Selected(formArray) {
let totalSelected = formArray.controls.reduce((selectedControls, control) =>
{
if (control.get('question').value) {
selectedControls++
}
return selectedControls;
}, 0)
return totalSelected > 3 ? { moreThanThreeSelected: true } : null;
}
并且您将更改 fb.array
以包含验证器函数
fb.array(this.questions.map(this.createQuestionControl(fb)), max3Selected)