binding data to angular checkbox

后端 未结 3 1013
伪装坚强ぢ
伪装坚强ぢ 2020-12-04 01:51

I managed to bind the data from this.empDetails.services correctly on the UI, checkboxes are checked correctly, and also listed all the checkboxes options.

3条回答
  •  再見小時候
    2020-12-04 02:15

    the "easy" way is to create a FormArray with values true/false. see the example in stackblitz

    Update:Correct some errors

    You fill the formArray using the data and the sservicesOptions

    getFormArrayService(data:any[]):FormArray
      {
        //e.g. data=['mopping','washingclothes']
        // return a FormArray and the value will be [false,true,false,true]
        //if data=null, return a FormArray [false,false,false,false]
        return new FormArray(
           this.sservicesOptions.map(x=>new FormControl(data?data.find(dat=>dat==x.value)?true:false:false))
        )
      }
    

    So, you can, in ngInit make some like

    ngOnInit()
      {
        this.updateSvcForm=new FormGroup({
          sservices:this.getFormArrayService(null)
        })
      }
    

    And in submitting the form, transform the value

      submit(updateSvcForm)
      {
          if (updateSvcForm.valid)
          {
              let services:string[]=[];
              updateSvcForm.value.sservices.forEach((x,index)=>
              {
                  if (x)
                     services.push(this.sservicesOptions.value)
              })
              const result={
                  ...updateSvcForm.value, //all value of the form but
                  sservices:services
              }
              console.log(result)
          }
      }
    

    The .html becomes like

    {{sservicesOptions[i].description}}
    {{updateSvcForm?.value|json}}

    The "not so easy way" a customFormControl, see an example in stackblitz

    Basically, we create a series of the checkbox, each change in checkbox return the "booleansToProp". In the example, I add a property "required", then indicate it is invalid if no check is checked and isString if we can return a string, not an array

    @Component({
      selector: 'check-box-group',
      template: `
          
    
          
    `, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CheckBoxGroupComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => CheckBoxGroupComponent), multi: true, } ], styles:[` .focused { outline: black dotted thin; }` ] }) export class CheckBoxGroupComponent implements ControlValueAccessor { @Input() set source(value) { this._source=value; //we need to know which column has the "value" and which column has the "text" //replace all extrange character else ":" and "," let aux=JSON.stringify(value[0]).replace(/[^\w|:|,\s]/gi, '').split(','); this._key=aux[0].split(':')[0] this._col=aux[1].split(':')[0] } get source() { return this._source; } _selectedItems: any[] = []; _source; _key: string; _col: string; _name:string=""; _isString:boolean=false; _isRequired:boolean=false; onChange; onTouched; constructor(el:ElementRef) { let name=el.nativeElement.getAttribute('name'); //we store in this._isRequired if the element has an attribute "required" this._isRequired=el.nativeElement.getAttribute('isRequired')!=null?true:false; //idem if the element has an attribute "isString" this._isString=el.nativeElement.getAttribute('isString')!=null?true:false; //Is necesary give a name to the control if there're severals check-box-group this._name=name?name:"ck"; } writeValue(value: any[]|any): void { this._selectedItems = this._isString? this.propsToBoolean(value?value.split(','):""):this.propsToBoolean(value); } registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: any): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { } //setValue is called each time you check/uncheck a checkbox //Simple call to this.onChange with the value o the result of the //function this.booleanToProps setValue(value: boolean, index: number) { this._selectedItems[index] = value; this.onChange(this._isString? this.booleanToProps(this._selectedItems).join(','): this.booleanToProps(this._selectedItems)); } validate(control: AbstractControl): ValidationErrors | null{ if (!this._isRequired) return null; if (!this._selectedItems.find(x=>x)) return {error:"you must select one option at last"} return null } //we received an array (or a string separated by commas) and //return an array of true/false propsToBoolean(props): any[] { let propsString=props?props.map(x=>''+x):null; return props ? this.source.map((x: any) => propsString.indexOf(''+x[this._key]) >= 0) : this.source.map(x => false); } //we received an array of true/false and return an array with the values //or with teh values separated by commas booleanToProps(propsBoolean: boolean[]) { let props: any[] = []; if (propsBoolean) { propsBoolean.forEach((item, index) => { if (item) props.push(this.source[index][this._key]) }) } return props; } }

提交回复
热议问题