将复选框控件与文本框控件关联的最佳方法 [英] Best way to associate checkbox control with textbox control

查看:156
本文介绍了将复选框控件与文本框控件关联的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试许多不同的方法,整个星期都失败了,我需要能够将复选框控件与答案相关联.

I've been trying many different methods have been failing all week, I need to be able to associate a checkbox control with an answer.

几乎,如果选中了该复选框,则用户必须回答该问题,并且必须具有最小长度为4的验证.

Pretty much, if the checkbox is checked then user must answer the question and it must have a validation of minlength 4.

该复选框将包含一个问题和答案.

The checkbox will contain a question and answer.

因此,如果用户选择了该问题,则他/她必须提供答案.

So if the user chooses that question he/she must provide an answer.

问题是从服务器中以诸如

the questions are rendered from the server in an object such as;

 { 
                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"
            }

如果需要,我可以发布我的代码,但是它很长而且很复杂.

I can post my code if required, it is however very long and complicated.

推荐答案

如果您创建反应型您可以动态更改验证

If you create a Reactive Form you can dynamically change the validation

组件

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()方法会将每个问题更改为一个控件,如下所示,表单生成器可以将其变成包含一个问题和一个答案的组

The createQuestionControl() method will change each question into a control as below which the form builder can turn into a group with a question and an answer

{ question: true, answer: ['', [Validators.required, Validators.minLength(4)]], index: 4 }

如果问题有所更改,changeValidator()方法将在答案上添加或删除验证器(注意:请不要忘记updateValueAndValidity)

The changeValidator() method will add or remove validators on the answer if the question is changed (note: do not forget 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>

在评论中进行澄清:

在给定时间最多可以检查5个

Maximum of 5 can be checked at a given time

我已经更新了数组,以使跨字段验证不超过3个(更容易测试,您可以将其更改为5个)

I have updated the array to have cross field validation of no more than 3 (easier to test you can change it to 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以包括验证器功能

and you would change the fb.array to include the validator function

fb.array(this.questions.map(this.createQuestionControl(fb)), max3Selected)

结果截图

实时监听器示例

这篇关于将复选框控件与文本框控件关联的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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