получение значений времени начала и окончания из опций выбора с помощью formArray Angular8 - PullRequest
0 голосов
/ 09 апреля 2020

В моей группе форм есть опции выбора времени начала и окончания в массиве формы, я хочу обновить массив времени окончания на основе времени начала.

<div [formGroupName]="skillIndex">

          Start at:
            <select  formControlName="skill"  id="skill">
             <option value="0" selected>Select</option>
              <option [value]="type" *ngFor="let type of startTimeArray">
                {{type}}
              </option>
           </select>
           End at:
          <select  formControlName="exp" id="exp">
             <option value="0" selected>Select</option>
              <option [value]="type" *ngFor="let type of endTimeArray">
                {{type}}
              </option>
          </select>
     </div>
</div>

предположим, пользователь выбрал начало время в 9 утра, то значения массива конечного времени в select должны go с 10:00 до 20:00, как в раскрывающемся списке времени окончания должно отображаться время между 10:00 и 20:00. теперь пользователь выбирает время окончания 1 вечера.

1005 *, а когда пользователь нажимает, «добавить время», появляются другие параметры выбора времени начала и окончания, здесь в массиве времени начала время должно быть от 14:00 до 20:00. , опять же, если пользователь выбирает время начала, скажем, в 3 часа дня, массив времени окончания должен быть между 16:00 и 20:00 ... и так далее, если пользователь снова нажимает «добавить время» (навык - это в основном мое время начала, а exp - мое время окончания )

Это немного сложно объяснить, пожалуйста, взгляните на стек стека https://stackblitz.com/edit/angular-r2sv3k

Ответы [ 3 ]

0 голосов
/ 09 апреля 2020

Здравствуйте, проверьте это решение с изменением ngModel и еще одним массивом для доступных времен окончания: html:

Start at:
            <select  formControlName="skill"  id="skill"  [(ngModel)]="selectedStartTime" (ngModelChange)="onRefresh()" >
             <option [ngValue]="null" selected>Select</option>
              <option [ngValue]="type" *ngFor="let type of startTimeArray">
                {{type}}
              </option>
           </select>
           End at:
          <select  formControlName="exp" id="exp">
             <option value="0" selected>Select</option>
              <option [value]="type" *ngFor="let type of availableEndTimes">
                {{type}}
              </option>
          </select>

и в файле yout ts:

selectedStartTime;
 availableEndTimes= [];
  constructor(private fb: FormBuilder) {
    this.empForm = this.fb.group({
      employees: this.fb.array([])
    });
    this.selectedStartTime= null;
  }
    onRefresh(){
  this.availableEndTimes = [...this.endTimeArray];
  let index =this.endTimeArray.indexOf(this.selectedStartTime);
   this.availableEndTimes.splice(0,index+1);
  console.log("available times",this.availableEndTimes);
}

Основной Идея состоит в том, что переменная selectedStartTime содержит значение времени начала. Массив availableEndTimes - это массив, который в начале является копией endTimeArray (содержит все доступные времена). Когда пользователь выбирает время запуска, мы объединяем (удаляя ненужные значения в функции refre sh ()) массив availableEndTimes (который теперь будет отображаться во втором окне выбора).

0 голосов
/ 09 апреля 2020

У вас есть две проблемы,

1.- Измените параметры в select

2.- отметьте, когда вы изменяете значение массива, если все правильно.

Прежде всего, я изменяю ваш массив startTimeArray, создавая массив объектов со значением и текстом. Массив похож на

  timeArray:any=[
     {value:700,text:"07:00 AM"},
     {value:800,text:"08:00 AM"},
     ...
     {value:1200,text: "12:00 PM"},
     {value:1300,text:  "1:00 PM"}
     ...
  ]

, что позволяет делать простые условия, потому что мы можем сравнивать «значение» (это числа), иначе, если трудно узнать, «1:00 PM» больше, чем «12:00 AM» в простом сравнении

Итак, мы можем использовать * ngIf, чтобы показать выбор. будь осторожен! используйте [ngValue] -not [значение], чтобы получить число, а я использую ноль, чтобы указать. Выберите

  <div [formGroupName]="skillIndex">
      {{skillIndex}}
      Start at:
        <select  formControlName="skill"  id="skill">
         <option [ngValue]="null" selected>Select</option>
         <ng-container *ngFor="let type of timeArray" >
          <option [ngValue]="type.value" 
              *ngIf="!skillIndex || 
                 employeeSkills(empIndex).value[skillIndex-1].exp<type.value">
            {{type.text}}
          </option>
          </ng-container>
       </select>
       End at:
      <select  formControlName="exp" id="exp">
         <option [ngValue]="null" selected>Select</option>
         <ng-container *ngFor="let type of timeArray">
          <option [ngValue]="type.value" 
             *ngIf="employeeSkills(empIndex).value[skillIndex].skill<type.value" >
            {{type.text}}
          </option>
         </ng-container>
      </select>

, см. условия *ngIf="!skillIndex || employeeSkills(empIndex).value[skillIndex-1].exp<type.value" и *ngIf="employeeSkills(empIndex).value[skillIndex].skill<type.value". Мы используем ng-container, потому что нам нужно использовать * ngFor и * ngIf, и мы не можем использовать в одном и том же «теге»

Что ж, другая часть - это управление, когда мы меняем массив. Это нам нужно сделать в функции newEmploye

  newEmployee(): FormGroup {
    const group=this.fb.group({
      firstName: "",
      lastName: [{value:'', disabled:true}],
      option1: [{value:false, disabled:true}],
      option2: [{value:false, disabled:true}],
      option3: [{value:false, disabled:true}],
      skills: this.fb.array([]),
      options: this.fb.array([])
    });
    group.get('skills').valueChanges.subscribe(res=>{
       res.forEach((x:any,index:number)=>{
         if (x.exp<x.skill)
         {
             const skill=(group.get('skills') as FormArray).at(index)
             skill.get('exp').setValue(null,{emitEvent:false})
         }
         if (index>0 && x.skill<res[index-1].exp)
         {
             const skill=(group.get('skills') as FormArray).at(index)
             skill.get('skill').setValue(null,{emitEvent:false})
         }


       })
    })
    return group;
  }

Посмотрите, как мы создаем переменную const group и возвращаем group. Перед подпиской на valueChanges

ваш раздвоенный стек (удалите ненужные функции)

0 голосов
/ 09 апреля 2020

Я отредактировал ваш стек, если будут внесены изменения, он решит вашу проблему, в противном случае вы можете заменить соответствующие файлы приведенным ниже кодом.

Замените html следующим:

<code><form [formGroup]="empForm" (ngSubmit)="onSubmit()">

    <div formArrayName="employees">

        <div *ngFor="let employee of employees().controls; let empIndex=index">

            <div [formGroupName]="empIndex" style="border: 1px solid blue; padding: 10px; width: 600px; margin: 5px;">
                {{empIndex}}
                First Name :
                <input type="text" formControlName="firstName">
         <label class="checkbox-inline">
                      <input type="checkbox" (change)="allow(empIndex, $event)" />ALLOW
        </label>

                <div>

        Last Name:
                <input type="text" formControlName="lastName">
                    <label class="checkbox-inline"  *ngFor="let day of days; ">
                        <input
                          type="checkbox"
                          formControlName="{{ day.name }}"
                          name="{{ day.name }}"
                           (change)="onChange(empIndex,day.value , $event.target.checked)"
                        />{{ day.value }}
                      </label>
                </div>
                <button (click)="removeEmployee(empIndex)">Remove</button>


                <div formArrayName="skills">

                    <div *ngFor="let skill of employeeSkills(empIndex).controls; let skillIndex=index">



                        <div [formGroupName]="skillIndex">
                            {{skillIndex}}


              Start at:
                <select (change)="onSelect($event.target.value)" formControlName="skill"  id="skill">
                 <option value="0" selected>Select</option>
                  <option  [value]="i" *ngFor="let type of startTimeArray; let i = index">
                    {{type}}
                  </option>
               </select>
               End at:
              <select *ngIf="enableEndTime" formControlName="exp" id="exp">
                 <option value="0" selected>Select</option>
                  <option [value]="type" *ngFor="let type of tempEndTimeArray">
                    {{type}}
                  </option>
              </select>




                            <button (click)="removeEmployeeSkill(empIndex,skillIndex)">Remove</button>

                            <pre>{{skillIndex.value |json}}
Добавить время

Отправить

Добавить сотрудника

имя фамилия умение и опыт дней
Form values: {{empForm.value | json}}

и ваш файл TS с этим:

import { Component } from "@angular/core";
import { FormGroup, FormArray, FormBuilder, FormControl } from "@angular/forms";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  forTableArray: any = [];
 startTimeArray:any=["07:00 AM","08:00 AM", "09:00 AM", "10:00 AM", "11:00 AM", "12:00 PM",  "1:00 PM",  "2:00 PM", "3:00 PM",  "4:00 PM", "5:00 PM",  "6:00 PM", "7:00 PM", "8:00 PM"];
  endTimeArray:any=["07:00 AM","08:00 AM", "09:00 AM", "10:00 AM", "11:00 AM", "12:00 PM",  "1:00 PM",  "2:00 PM", "3:00 PM",  "4:00 PM", "5:00 PM",  "6:00 PM", "7:00 PM", "8:00 PM"];
  public tempEndTimeArray: Array<any>;
  title = "Nested FormArray Example Add Form Fields Dynamically";
  public enableEndTime: boolean = false;
  selectedEmp = 0;
  empForm: FormGroup;
  days: any = [
    {
      id: 1,
      name: "option1",
      isActive: false,

      value: "option1"
    },
    {
      id: 2,
      name: "option2",
      isActive: false,

      value: "option2"
    },
    {
      id: 3,
      name: "option3",
      isActive: false,

      value: "option3"
    }
  ];

  constructor(private fb: FormBuilder) {
    this.empForm = this.fb.group({
      employees: this.fb.array([])
    });
  }

  employees(): FormArray {
    return this.empForm.get("employees") as FormArray;
  }

  onChange(empIndex, day: string, isChecked: boolean) {
    const dayFormArray = (this.empForm.get("employees") as FormArray)
      .at(empIndex)
      .get("options") as FormArray;
    if (isChecked) {
      dayFormArray.push(new FormControl(day));
    } else {
      let index = (dayFormArray.value as []).findIndex(item => item === day);
      dayFormArray.removeAt(index);
    }
  }
  newEmployee(): FormGroup {
    return this.fb.group({
      firstName: "",
      lastName: [{value:'', disabled:true}],
      option1: [{value:false, disabled:true}],
      option2: [{value:false, disabled:true}],
      option3: [{value:false, disabled:true}],
      skills: this.fb.array([]),
      options: this.fb.array([])
    });
  }

allow(index,event){
  const status = event.target.checked ? 'enable' : 'disable' ;
  this.employees().at(index).get('lastName')[status]();
    this.employees().at(index).get('option1')[status]();
      this.employees().at(index).get('option2')[status]();
        this.employees().at(index).get('option3')[status]();
        if(!event.target.checked){
  this.employees().at(index).get('lastName')['reset']();
    this.employees().at(index).get('option1')['reset'](false);
      this.employees().at(index).get('option2')['reset'](false);
        this.employees().at(index).get('option3')['reset'](false);
 this.employees().at(index).get('options')['reset']("");

        }
}

  addEmployee() {
    console.log("Adding a employee");
    this.employees().push(this.newEmployee());
  }

  removeEmployee(empIndex: number) {
    this.employees().removeAt(empIndex);
  }

  employeeSkills(empIndex: number): FormArray {
    return this.employees()
      .at(empIndex)
      .get("skills") as FormArray;
  }

  newSkill(): FormGroup {
    return this.fb.group({
      skill: "",
      exp: "",
      fromT:"",
      toT:""
    });
  }

  addEmployeeSkill(empIndex: number) {
    this.employeeSkills(empIndex).push(this.newSkill());
  }

  removeEmployeeSkill(empIndex: number, skillIndex: number) {
    this.employeeSkills(empIndex).removeAt(skillIndex);
  }

  onSubmit() {
    const employee = this.employees().value.map((_, i: number) =>
      this.mapFormEmployee(i)
    );
    const body = {
      displayText: true,
      employee: employee
    };
    this.forTableArray = body;
    console.log(body);
  }

  private mapFormEmployee(
    empIndex: number
  ): {
    firstName: string;
    lastName: string;
    option1: boolean;
    option2: boolean;
    option3: boolean;
    options:[];
    skills: { skill: string; exp: string }[];
  } {
    const employeeFormGroup = this.employees().at(empIndex);

    return {
      firstName: employeeFormGroup.get("firstName").value,
      lastName: employeeFormGroup.get("lastName").value,
      option1: employeeFormGroup.get("option1").value,
      option2: employeeFormGroup.get("option2").value,
      option3: employeeFormGroup.get("option3").value,
      options: employeeFormGroup.get("options").value,
      skills: employeeFormGroup
        .get("skills")
        .value.map((_, skillIndex) => this.mapFormSkill(empIndex, skillIndex))
    };
  }

  private mapFormSkill(
    empIndex: number,
    skillIndex: number
  ): { skill: string; exp: string } {
    const employeeFormGroup = this.employees().at(empIndex);
    const skillFormGroup = (employeeFormGroup.get("skills") as FormArray).at(
      skillIndex
    );

    return {
      skill: skillFormGroup.get("skill").value,
      exp: skillFormGroup.get("exp").value
    };
  }

  employeeFirstName(empIndex: number): string {
    return this.employees()
      .at(empIndex)
      .get("firstName").value;
  }

  employeeLastName(empIndex: number): string {
    return this.employees()
      .at(empIndex)
      .get("lastName").value;
  }
  getEmployeeSkill(employeeIdx: number, skillIdx: number) {
    const employee = this.empForm.value.employees[employeeIdx];
    if (employee === undefined) return null;
    return employee.skills.length === 0
      ? null
      : employee.skills.map(skill => skill.skill)[skillIdx];
  }

  getEmployeeExp(employeeIdx: number, skillIdx: number) {
    const employee = this.getEmployeeFormGroup(employeeIdx);
    return employee.value.skills.map(skill => skill.skill);
  }

  getEmployeeSkills(index: number): string[] {
    const employee = this.getEmployeeFormGroup(index);
    return employee.value.skills.map(skill => skill.skill);
  }

  private getEmployeeFormGroup(index: number): FormGroup {
    return this.employees().at(index) as FormGroup;
  }
public onSelect(val){
  console.log(val)
  let index = parseInt(val) + 1;
  console.log(index)
  this.enableEndTime = true;
  this.tempEndTimeArray = this.endTimeArray.slice(index);

}
}


export class country {
  id: string;
  name: string;

  constructor(id: string, name: string) {
    this.id = id;
    this.name = name;
  }
}
  // onCheckChange(event){
  //   const formArray: FormArray = this.empForm.get('myChoices') as FormArray
  //    if(event.target.checked){
  //     // Add a new control in the arrayForm
  //     formArray.push(new FormControl(event.target.value));
  //   }else{
  //      let i: number = 0;
  //  formArray.controls.forEach((ctrl: FormControl) => {
  // if(ctrl.value == event.target.value) {
  //         // Remove the unselected element from the arrayForm
  //         formArray.removeAt(i);
  //         return;
  //       }

  //       i++;
  //  });
  //   }
  // }
  // get selectedOptions() { // right now: ['1','3']
  //     return this.days
  //               .filter(opt => opt.checked)
  //               .map(opt => opt.value)
  //   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...