# All files / src/app/shared/components/submit-button submit-button.component.ts

73.53% Statements 25/34
66.67% Branches 2/3
50% Functions 3/6
67.86% Lines 19/28

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
    8795x
    95x

    95x

    95x

    95x

    223x

    223x

    223x

    223x

    223x

    197x
    197x

    17x
    17x

    1x

    95x

    95x

    95x

    95x
     import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core';
    import { AbstractControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms';

    import * as _ from 'lodash';

    /**
     * This component will render a submit button with the given label.
     *
     * The button will disabled itself and show a loading icon when the user clicks
     * it, usually initiating a request to the server, and it will stay in that
     * state until the request is finished.
     *
     * To indicate that the request failed, returning the button to the enable
     * state, you need to insert an error in the form with the 'cdSubmitButton' key.
     * p.e.: this.rbdForm.setErrors({'cdSubmitButton': true});
     *
     * It will also check if the form is valid, when clicking the button, and will
     * focus on the first invalid input.
     *
     * @export
     * @class SubmitButtonComponent
     * @implements {OnInit}
     */
    @Component({
      selector: 'cd-submit-button',
      template: require('./submit-button.component.html'),
      styles: []
    })
    export class SubmitButtonComponent implements OnInit {
      @Input()
      form: FormGroup | NgForm;
      @Input()
      type = 'submit';
      @Output()
      submitAction = new EventEmitter();
      @Input()
      disabled = false;

      loading = false;

      constructor(private elRef: ElementRef) {}

      ngOnInit() {
        this.form.statusChanges.subscribe(() => {
          if (_.has(this.form.errors, 'cdSubmitButton')) {
            this.loading = false;
            _.unset(this.form.errors, 'cdSubmitButton');
            // Handle Reactive forms.
            if (this.form instanceof AbstractControl) {
              (<AbstractControl>this.form).updateValueAndValidity();
            }
          }
        });
      }

      submit($event) {
        this.focusButton();

        // Special handling for Template driven forms.
        if (this.form instanceof FormGroupDirective) {
          (<FormGroupDirective>this.form).onSubmit($event);
        }

        if (this.form.invalid) {
          this.focusInvalid();
          return;
        }

        this.loading = true;
        this.submitAction.emit();
      }

      focusButton() {
        this.elRef.nativeElement.offsetParent.querySelector(`button[type="${this.type}"]`).focus();
      }

      focusInvalid() {
        const target = this.elRef.nativeElement.offsetParent.querySelector(
          'input.ng-invalid, select.ng-invalid'
        );

        if (target) {
          target.focus();
        }
      }
    }