]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
1ef6cb2ffb5160cfe50ea88e217d26b212380970
[ceph-ci.git] /
1 import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core';
2 import { AbstractControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms';
3 import { Icons } from '../../../shared/enum/icons.enum';
4
5 import * as _ from 'lodash';
6
7 /**
8  * This component will render a submit button with the given label.
9  *
10  * The button will disabled itself and show a loading icon when the user clicks
11  * it, usually initiating a request to the server, and it will stay in that
12  * state until the request is finished.
13  *
14  * To indicate that the request failed, returning the button to the enable
15  * state, you need to insert an error in the form with the 'cdSubmitButton' key.
16  * p.e.: this.rbdForm.setErrors({'cdSubmitButton': true});
17  *
18  * It will also check if the form is valid, when clicking the button, and will
19  * focus on the first invalid input.
20  *
21  * @export
22  * @class SubmitButtonComponent
23  * @implements {OnInit}
24  */
25 @Component({
26   selector: 'cd-submit-button',
27   templateUrl: './submit-button.component.html',
28   styleUrls: ['./submit-button.component.scss']
29 })
30 export class SubmitButtonComponent implements OnInit {
31   @Input()
32   form: FormGroup | NgForm;
33
34   @Input()
35   type = 'submit';
36
37   @Input()
38   disabled = false;
39
40   // A CSS class string to apply to the button's main element.
41   @Input()
42   btnClass: string;
43
44   @Output()
45   submitAction = new EventEmitter();
46
47   loading = false;
48   icons = Icons;
49
50   constructor(private elRef: ElementRef) {}
51
52   ngOnInit() {
53     this.form.statusChanges.subscribe(() => {
54       if (_.has(this.form.errors, 'cdSubmitButton')) {
55         this.loading = false;
56         _.unset(this.form.errors, 'cdSubmitButton');
57         // Handle Reactive forms.
58         if (this.form instanceof AbstractControl) {
59           (<AbstractControl>this.form).updateValueAndValidity();
60         }
61       }
62     });
63   }
64
65   submit($event: any) {
66     this.focusButton();
67
68     // Special handling for Template driven forms.
69     if (this.form instanceof FormGroupDirective) {
70       (<FormGroupDirective>this.form).onSubmit($event);
71     }
72
73     if (this.form.invalid) {
74       this.focusInvalid();
75       return;
76     }
77
78     this.loading = true;
79     this.submitAction.emit();
80   }
81
82   focusButton() {
83     this.elRef.nativeElement.offsetParent.querySelector(`button[type="${this.type}"]`).focus();
84   }
85
86   focusInvalid() {
87     const target = this.elRef.nativeElement.offsetParent.querySelector(
88       'input.ng-invalid, select.ng-invalid'
89     );
90
91     if (target) {
92       target.focus();
93     }
94   }
95 }