All files / app/formly duration.type.ts

27.27% Statements 12/44
42.85% Branches 9/21
18.75% Functions 3/16
20% Lines 5/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 9010x       10x                                           18x         10x                                                                     10x                                              
import { ChangeDetectionStrategy, Component, Directive, ElementRef, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
import { FieldType, FieldTypeConfig, FormlyAttributes, FormlyConfig } from '@ngx-formly/core';
import { Duration } from 'luxon';
import { getErrorMessage } from './errors';
 
@Component({
  selector: 'formly-field-duration',
  host: { 'class': 'field' },
  template: `
    <div class="col">
      <div class="center">{{ formatInterval(model[$any(key)]) }}</div>
      <input [duration]="props.datalist"
             type="range"
             min="0"
             [style.display]="'block'"
             [max]="props.datalist?.length || 10"
             step="1"
             (blur)="validate($any($event.target))"
             [formControl]="formControl"
             [formlyAttributes]="field"
             [class.is-invalid]="showError">
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    ReactiveFormsModule,
    forwardRef(() => DurationInputAccessor),
    FormlyAttributes,
  ],
})
export class FormlyFieldDuration extends FieldType<FieldTypeConfig> {
 
  constructor(
    private config: FormlyConfig,
  ) {
    super();
  }
 
  validate(input: HTMLInputElement) {
    if (this.showError) {
      input.setCustomValidity(getErrorMessage(this.field, this.config));
      input.reportValidity();
    }
  }
 
  formatInterval(value: string) {
    return Duration.fromISO(value).toHuman();
  }
}
 
@Directive({
  selector: '[duration]',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DurationInputAccessor),
      multi: true
    },
  ],
  host: {
    '(change)': 'onChange($any($event.target).value)',
    '(input)': 'onChange($any($event.target).value)',
    '(blur)': 'onTouched()'
  },
})
export class DurationInputAccessor implements ControlValueAccessor {
  onChange: any;
  onTouched: any;
 
  @Input('duration')
  datalist: { value: string, label: string }[] = [];
 
  constructor(private elementRef: ElementRef) {}
 
  writeValue(value: any) {
    this.elementRef.nativeElement.value = this.datalist.findIndex(o => o.value === value);
  }
 
  registerOnChange(fn: any) {
    this.onChange = (value: any) => {
      fn(this.datalist[value].value);
    };
  }
 
  registerOnTouched(fn: any) {
    this.onTouched = fn;
  }
}