在 Angular 8 中使用动态表单创建复选框

约翰斯克

嗨,我正在 Angular 8 中构建一个动态表单。到目前为止一切正常,但我在实现复选框控件时遇到了麻烦。复选框控件出现了,我试着看看它是否被选中。

如果它在 meta.json 文件中设置为 true,我在网页上单击它,则该值变为“true”。我希望是假的。如果meta.json中的值为false,则单击时网页上没有变化。

元.json

[ 
  [
    {
      "questionType": "dropdown",
      "key": "brave",
      "label": "Bravery Rating",
      "options": [
        {"key": "solid", "value": "Solid"},
        {"key": "great", "value": "Great", "selected": "selected"},
        {"key": "good", "value": "Good"},
        {"key": "unproven", "value": "Unproven"}
      ],
      "order": 3,
      "visibility": true
    },
    {
      "questionType": "checkbox",
      "key": "mycheck01",
      "label": "Mycheck01",
      "value": true,
      "type": "checkbox",
      "validators": [],
      "order": 2,
      "visibility": true
    },
    {
      "questionType": "textbox",
      "key": "firstName",
      "label": "First name",
      "value": "abcd",
      "type": "text",
      "validators": ["required"],
      "order": 2,
      "visibility": true
    },
    {
      "questionType": "textbox",
      "key": "emailAddress",
      "label": "Email",
      "value": "[email protected]",
      "type": "email",
      "order": 1,
      "validators": ["required", "email"],
      "visibility": "this.form.get('firstName').value === 'abc'"
    }
  ],
  [
    {
      "questionType": "textbox",
      "key": "emailAddress",
      "label": "Email",
      "value": "",
      "type": "email",
      "order": 2,
      "visibility": true
    }
  ]
]

主组件.html

<div *ngIf="loaded">
  <h2>POC</h2>
  <form (ngSubmit)="onSubmit()" [formGroup]="form">
    <ng-container *ngFor="let eachGroup of objectKeys(globalForm); let index = index">
      <button (click)="openGroupHadler(index)">click me</button> <br>
      <div 
        [formGroupName]="eachGroup" 
        class="form-group"
        [ngClass]="{'active' : index === activeGroup}">
        <div *ngFor="let question of globalForm[eachGroup]" class="form-row">
          <app-question [question]="question" [form]="form.controls[eachGroup]"></app-question>
        </div>
      </div>
    </ng-container>
    <div class="form-row">
      <button type="submit" [disabled]="!form.valid">Save</button>
    </div>
  </form>

  <pre>
    {{form.value | json}}
  </pre>
  <div *ngIf="payLoad" class="form-row">
    <strong>Saved the following values</strong><br>{{payLoad}}
  </div>
</div>

main.component.ts

import { Component, OnInit } from '@angular/core';
import { HeaderService } from '@myHeaderService';
import { QuestionService } from '../../question/services/question.service';
import { QuestionControlService } from '../../question/services/question-control.service';
import { FormGroup } from '@angular/forms';
import { FControlTextbox } from '../../question/model/question-textbox';
import { FControlDropdown } from '../../question/model/question-dropdown';
import { FControlCheckbox } from '../../question/model/question-checkbox';

@Component({
  selector: 'app-irv',
  templateUrl: './irv.component.html',
  styleUrls: ['./irv.component.scss']
})
export class IrvComponent implements OnInit {
  labels;
  objectKeys = Object.keys;
  form: FormGroup;
  payLoad = '';
  loaded = false;
  globalForm: any = {};
  activeGroup;

  constructor(
    private _headerService: HeaderService,
    private _questionService: QuestionService,
    private _questionControlService: QuestionControlService
    ) {}

  ngOnInit() {
    this.labels = JSON.parse(localStorage.getItem('labels'));

    this._headerService.updateHeader({
      title: 'HC - Irv',
      back: true
    });

    this._questionService.getQuestions().subscribe((response: any[]) => {
      response.forEach((group, index) => { // loop thrugh groups
        const formControls = [];

        group.forEach(formControl => { // loop through form controls in groups
          switch (formControl.questionType) {
            case 'textbox':
              formControls.push(new FControlTextbox(formControl)); break;
            case 'checkbox':
              formControls.push(new FControlCheckbox(formControl)); break;
            case 'dropdown':
              formControls.push(new FControlDropdown(formControl)); break;
            default:
              break;
          }
        });
        console.log(this.globalForm);
        this.globalForm['group' + (index + 1)] = formControls.sort((a, b) => a.order - b.order);
      });

      this.form = this._questionControlService.toFormGroup(this.globalForm);
      this.loaded = true;
    });
  }

  onSubmit() {
    this.payLoad = JSON.stringify(this.form.value);
  }

  openGroupHadler(index) {
    this.activeGroup === index ? this.activeGroup = null : this.activeGroup = index; // show or hide a formgroup
  }

}

question.component.ts

import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';

import { QuestionBase } from './model/question-base';

@Component({
  selector: 'app-question',
  templateUrl: './question.component.html',
  styleUrls: ['./question.component.scss']
})
export class QuestionComponent {
  @Input() question: QuestionBase<any>;
  @Input() form: FormGroup;
  get isValid() { return (
    (
      this.form.controls[this.question.key].valid &&
      this.form.controls[this.question.key].dirty
    ) ||
    (
      this.form.controls[this.question.key].untouched
    ) ||
    (
      !this.form.controls[this.question.key].invalid
    )
    );
  }

  isVisible(value) {
    return eval(value);
  }
}

问题.component.html

<div [formGroup]="form" 
  [ngClass]="{'isa_error':isValid ? false : true}" 
  *ngIf="isVisible(question.visibility)"
  >
    <label [attr.for]="question.key">{{question.label}}</label>

  <div [ngSwitch]="question.controlType">
    <input
      *ngSwitchCase="'textbox'"
      [formControlName]="question.key"
      [id]="question.key"
      [type]="question['type']">

    <input
      *ngSwitchCase="'checkbox'"
      [formControlName]="question.key"
      [checked]="question['checked']"
      [id]="question.key"
      [type]="question['type']">

    <select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key">
      <option 
        *ngFor="let opt of question['options']" 
        [value]="opt.key"
        >{{opt.value}}</option>
    </select>
  </div> 

  <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>

问题.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class QuestionService {
  constructor(
    private _http: HttpClient
  ) {}
  getQuestions() {
    return this._http.get('./assets/meta.json').pipe(res => res);
  }
}

question.control.service.ts

import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

import { QuestionBase } from '../model/question-base';

@Injectable({
  providedIn: 'root'
})
export class QuestionControlService {
  constructor() { }

  toFormGroup(questions: QuestionBase<any>[] ) {
    let group: any = {};
    const sections: {} = {};
    Object.keys(questions).forEach((eachgroup: string) => {
      group = {};
      questions[eachgroup].forEach(question => {
        const validators = [];
        if (question.validators) {
          question.validators.forEach(element => {
            switch (element) {
              case 'required': validators.push(Validators.required); break;
              case 'email': validators.push(Validators.email); break;
            }
          });
          group[question.key] = new FormControl(question.value || '', validators);
        } else {
          group[question.key] = new FormControl(question.value || '');
        }
      });
      sections[eachgroup] = new FormGroup(group);
    });

    return new FormGroup(sections);
  }
}

question.textbox.ts

import { QuestionBase } from './question-base';

export class FControlTextbox extends QuestionBase<string> {
  controlType = 'textbox';
  type: string;

  constructor(options) {
    super(options);
    this.type = options.type || '';
  }
}

question.dropdown.ts

import { QuestionBase } from './question-base';

export class FControlDropdown extends QuestionBase<string> {
  controlType = 'dropdown';
  options: {key: string, value: string}[] = [];

  constructor(options) {
    super(options);
    this.options = options.options || [];
  }
}

问题库.ts

export class QuestionBase<T> {
  value: T;
  key: string;
  label: string;
  required: boolean;
  order: number;
  controlType: string;
  visibility: string;
  validators: string;

  constructor(options: {
      value?: T,
      key?: string,
      label?: string,
      required?: boolean,
      order?: number,
      controlType?: string,
      visibility?: string
      validators?: string
    } = {}) {
    this.value = options.value;
    this.key = options.key || '';
    this.label = options.label || '';
    this.required = !!options.required;
    this.order = options.order === undefined ? 1 : options.order;
    this.controlType = options.controlType || '';
    this.visibility = options.visibility;
    this.validators = options.validators;
  }
}

question.checkbox.ts

import { QuestionBase } from './question-base';

export class FControlCheckbox extends QuestionBase<string> {
  controlType = 'checkbox';
  type: string;
  checked: boolean;

  constructor(options) {
    super(options);
    this.type = options.type || '';
    this.checked = options.checked || false;
  }
}

阿斯达

约翰斯克

事实证明它实际上很简单。我刚刚添加了检查属性和更改属性

问题.component.html

<div [formGroup]="form" 
  [ngClass]="{'isa_error':isValid ? false : true}" 
  *ngIf="isVisible(question.visibility)"
  >
    <label [attr.for]="question.key">{{question.label}}</label>

  <div [ngSwitch]="question.controlType">
    <input
      *ngSwitchCase="'textbox'"
      [formControlName]="question.key"
      [id]="question.key"
      [type]="question['type']">

    <input
      *ngSwitchCase="'checkbox'"
      [formControlName]="question.key"
      [checked]="question['value']"
      [id]="question.key"
      (change)="form.controls[question.key].setValue($event.target.checked)"
      [type]="'checkbox'">

    <select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key">
      <option 
        *ngFor="let opt of question['options']" 
        [value]="opt.key"
        >{{opt.value}}</option>
    </select>
  </div> 

  <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Angular 8反应形式:不可单击复选框

来自分类Dev

Angular8复选框布尔过滤器

来自分类Dev

Angular8复选框布尔过滤器

来自分类Dev

在Angular 2中使用管道过滤复选框

来自分类Dev

在Angular 2中使用管道过滤复选框

来自分类Dev

JSON的Angular 8动态表单

来自分类Dev

如何在复选框Angular 8的复选框中以逗号分隔的字符串连接值

来自分类Dev

带有复选框的Angular 2动态表单不起作用?

来自分类Dev

Angular4:如何构建要在表单中提交的动态复选框列表?

来自分类Dev

如何为Angular中动态创建的复选框定义模型

来自分类Dev

使用Angular获取复选框的价值

来自分类Dev

带有枚举和复选框的Angular 8反应形式

来自分类Dev

在Angular 8中管理复选框状态的正确方法是什么?

来自分类Dev

将多个条件应用于Angular 8应用中的复选框时发生

来自分类Dev

使用来自API的数据填充“编辑”表单复选框-Angular

来自分类Dev

在Angular表单上更改$ scope变量复选框

来自分类Dev

angular ng-disable复选框不使用动态源更新

来自分类Dev

如何使用Angular.js / Javascript在点击事件中动态选中复选框

来自分类Dev

如何禁用Angular 6中的特定动态复选框?

来自分类Dev

Angular和JSON API中的动态复选框列表

来自分类Dev

Angular 6 Reactive Forms 动态复选框

来自分类Dev

在 PHP 中使用 Angular 保存动态创建的表单数据

来自分类Dev

Angular patchValue() 复选框

来自分类Dev

Angular JS复选框使用$ watch来计数选中的复选框

来自分类Dev

动态绑定图像Angular 8

来自分类Dev

Angular 2使用ngFor设置和绑定复选框

来自分类Dev

使用angular js的multiselectable下拉复选框

来自分类Dev

使用复选框在Angular中显示或隐藏按钮

来自分类Dev

使用复选框选择项Angular JS

Related 相关文章

  1. 1

    Angular 8反应形式:不可单击复选框

  2. 2

    Angular8复选框布尔过滤器

  3. 3

    Angular8复选框布尔过滤器

  4. 4

    在Angular 2中使用管道过滤复选框

  5. 5

    在Angular 2中使用管道过滤复选框

  6. 6

    JSON的Angular 8动态表单

  7. 7

    如何在复选框Angular 8的复选框中以逗号分隔的字符串连接值

  8. 8

    带有复选框的Angular 2动态表单不起作用?

  9. 9

    Angular4:如何构建要在表单中提交的动态复选框列表?

  10. 10

    如何为Angular中动态创建的复选框定义模型

  11. 11

    使用Angular获取复选框的价值

  12. 12

    带有枚举和复选框的Angular 8反应形式

  13. 13

    在Angular 8中管理复选框状态的正确方法是什么?

  14. 14

    将多个条件应用于Angular 8应用中的复选框时发生

  15. 15

    使用来自API的数据填充“编辑”表单复选框-Angular

  16. 16

    在Angular表单上更改$ scope变量复选框

  17. 17

    angular ng-disable复选框不使用动态源更新

  18. 18

    如何使用Angular.js / Javascript在点击事件中动态选中复选框

  19. 19

    如何禁用Angular 6中的特定动态复选框?

  20. 20

    Angular和JSON API中的动态复选框列表

  21. 21

    Angular 6 Reactive Forms 动态复选框

  22. 22

    在 PHP 中使用 Angular 保存动态创建的表单数据

  23. 23

    Angular patchValue() 复选框

  24. 24

    Angular JS复选框使用$ watch来计数选中的复选框

  25. 25

    动态绑定图像Angular 8

  26. 26

    Angular 2使用ngFor设置和绑定复选框

  27. 27

    使用angular js的multiselectable下拉复选框

  28. 28

    使用复选框在Angular中显示或隐藏按钮

  29. 29

    使用复选框选择项Angular JS

热门标签

归档