zoukankan      html  css  js  c++  java
  • Form中可手动添加输入框,并可以删除

    组件:

    style:

    .w-forbid {
      background-color: #ddd;
      border: 1px dashed #ddd;
    }
    
    .dynamic-delete-button {
      cursor: pointer;
      position: relative;
      top: 4px;
      font-size: 24px;
      color: #999;
      transition: all .3s;
    }
    
    .for-del {
    
      12px;
      height:12px;
    
      &:hover {
        color: #108ee9;
      }
    }

    html:

        <div class="dynamic-input-num">    
    <input
    #eleInput type
    ="text" [ngModel]="value" style="display: none;" /> <button *ngIf="!isView" nz-button [nzType]="'dashed'" [nzShape]="'circle'" [nzSize]="'large'" (click)="addField($event, eleInput)">
        <!-- 添加按钮 --> 
        <i class="anticon anticon-plus"></i>
          </button>
      <div nz-col class="w-forbid clearfix" *ngIf="collectValue.length > 0">
    
        <div *ngFor="let control of collectValue;let i = index" nz-form-control nz-col [nzSpan]="8">
          <div style=" 70%;display: inline-block;">
          <!-- 每一项内容 --> <input #eleOneInput [(ngModel)]="control.controlInstance" (ngModelChange)="changeOne($event, control.id, eleOneInput)" (blur)="getChange($event, control.id, eleInput)" /> <span *ngIf="isView">{{control.controlInstance}}</span> </div>
        <!-- 删除按钮 --> <i class="anticon anticon-delete for-del" (click)="removeField(control,$event,eleInput)"></i> </div> </div> </div>

    js:

    import { Component, OnInit, Input, ViewChild, ElementRef, EventEmitter, Output, forwardRef } from '@angular/core';
    import { NG_VALUE_ACCESSOR } from '@angular/forms';
    import { ControlValueAccessor } from '@angular/forms/src/directives';
    
    const RADIO_VALUE_ACCESSOR = {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DynamicInputNumComponent),
      multi: true
    };
    
    @Component({
      // tslint:disable component-selector
      selector: 'dynamic-input-num',
      templateUrl: './dynamic-input-num.component.html',
      styleUrls: ['./dynamic-input-num.component.scss'],
      providers: [RADIO_VALUE_ACCESSOR]
    })
    
    export class DynamicInputNumComponent implements OnInit, ControlValueAccessor {
      @Output()
      public valueChange: EventEmitter<any> = new EventEmitter();
    
      @Input() isView: boolean;
      public collectValue = [];
    
      public controlArray = [];
      private onTouchedCallback: Function = function () { };
      private onChangeCallback: Function = function () { };
    
      public get value() {
        return this.collectValue;
      }
    
      public addField(e: MouseEvent, ipt) {
        if (e) {
          e.preventDefault();
        }
        const id = (this.collectValue.length > 0) ? this.collectValue[this.collectValue.length - 1].id + 1 : 0;
        if (id > 19) {
          return;
        }
        if ( this.collectValue.length > 0 && this.collectValue[this.collectValue.length - 1].controlInstance.trim() === '') {
          return;
        }
        const control = {
          id,
          controlInstance: ''
        };
        this.collectValue.push(control);
    
        ipt.value = this.collectValue;
        this.triggerEvent(ipt, 'input');
        this.emitEvent();
      }
    
      public removeField(i, e: MouseEvent, ipt) {
        e.preventDefault();
        if (this.collectValue.length > 0) {
          const index = this.collectValue.indexOf(i);
          this.collectValue.splice(index, 1);
    
          ipt.value = this.collectValue;
          this.triggerEvent(ipt, 'input');
          this.emitEvent();
        }
      }
    
      public changeOne(value, id, ipt) {
        ipt.value = value;
      }
    
      public getChange(value, id, ipt) {
        ipt.value = this.collectValue.toString();
        this.triggerEvent(ipt, 'input');
        this.emitEvent();
      }
    
      private triggerEvent(el, type) {
        const e = document.createEvent('HTMLEvents');
        e.initEvent(type, true, true);
        el.dispatchEvent(e);
      }
    
      public writeValue(value: any) {
        if (value && value !== this.collectValue) {
          this.collectValue = value;
        }
      }
    
      public setDisabledState?(isDisabled: boolean) {}
      public registerOnChange(fn: Function) {
        this.onChangeCallback = fn;
      }
    
      public registerOnTouched(fn: Function) {
        this.onTouchedCallback = fn;
      }
    
      public emitEvent() {
        const value = this.collectValue;
        this.valueChange.emit(value);
      }
    
      ngOnInit() {}
    
    }

    module:

    import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FormsModule } from '@angular/forms';
    import { NgZorroAntdModule } from 'ng-zorro-antd';
    import { DynamicInputNumComponent } from './dynamic-input-num.component';
    
    @NgModule({
      imports: [
        CommonModule,
        FormsModule,
        NgZorroAntdModule.forRoot(),
      ],
      declarations: [
        DynamicInputNumComponent,
      ],
      exports: [
        DynamicInputNumComponent,
      ]
    })
    export class DynamicInputNumModule { }

    使用:

    在module中加入

    import { DynamicInputNumModule } from '../dynamic-input-num/dynamic-input-num.module';
    
    @NgModule({
      imports: [
        DynamicInputNumModule
      ]
    })

    html:

    <div nz-form-item nz-row>
            <div nz-form-label nz-col [nzSm]="2" [nzXs]="2" style="text-align: left;">名称</div>
            <div nz-form-control nz-col [nzSm]="9" [nzXs]="9" [nzValidateStatus]="getFormControl('mallBanned')">
              <dynamic-input-num *ngIf="!isView" formControlName="mallBanned" [isView]="isView"></dynamic-input-num>
              <span *ngIf="isView">{{searchForm.mallBanned}}</span>
            </div>
    
          </div>

    js:

    this.validateForm = this.fb.group({
          mallBanned: [[], []],
        });
    
    // 保存
      public toSave() {
        this._submitForm();
        const param = {
          banned: this.getBanned(this.searchForm.banned),
        }
    }
    
    // 表单提交
      public _submitForm() {
        if (this.validateForm && this.validateForm.controls) {
          for (const i in this.validateForm.controls) {
            if (this.validateForm.controls[i]) {
              this.searchForm[i] = this.validateForm.controls[i].value;
            }
          }
        }
      }
    
      public getFormControl(name) {
        return this.validateForm.controls[name];
      }
    
    // 获取字符串转化为对应数组
    private setBanned(banned) {
        const controlArray = [];
        if (banned) {
          banned = banned + '';
          let arr = [];
          arr = banned.split(',');
          arr.forEach((item, i) => {
            if (item.controlInstance !== '') {
              controlArray.push({
                id: i,
                controlInstance: item
              });
            }
          });
        }
        return controlArray;
      }
    
    // 保存时将数组转化为字符串
      private getBanned(controlArray) {
        const banned = [];
        controlArray.forEach((item) => {
          if (item.controlInstance !== '') {
            banned.push(item.controlInstance);
          }
        });
        return banned.toString();
      }
  • 相关阅读:
    背包解法
    第十六周周总结
    软件工程个人课程总结
    学期课后个人总结
    spring事务
    梦断代码03
    团队冲刺的第二十四天
    第十五周周总结
    百度输入法评价
    找到水王
  • 原文地址:https://www.cnblogs.com/zhuangcui/p/12133735.html
Copyright © 2011-2022 走看看