Browse Source

refactor(admin-ui): Move readOnly toggle into FormFieldComponent

Michael Bromley 7 years ago
parent
commit
8380be000b

+ 2 - 8
admin-ui/src/app/catalog/components/create-option-group-form/create-option-group-form.component.html

@@ -3,14 +3,8 @@
         <vdr-form-field [label]="'catalog.option-group-name' | translate" for="name">
             <input id="name" type="text" formControlName="name" (input)="updateCode($event.target.value)">
         </vdr-form-field>
-        <vdr-form-field [label]="'catalog.option-group-code' | translate" for="code">
-            <div class="code-input">
-                <input id="code" type="text" formControlName="code" [readonly]="!editCode">
-                <button type="button" class="btn btn-icon btn-sm"
-                        (click)="editCode = true">
-                    <clr-icon shape="edit"></clr-icon>
-                </button>
-            </div>
+        <vdr-form-field [label]="'catalog.option-group-code' | translate" for="code" [readOnlyToggle]="true">
+            <input id="code" type="text" formControlName="code">
         </vdr-form-field>
         <vdr-form-field [label]="'catalog.option-group-options-label' | translate"
                         [tooltip]="'catalog.option-group-options-tooltip' | translate: { defaultLanguage: defaultLanguage }"

+ 0 - 14
admin-ui/src/app/catalog/components/create-option-group-form/create-option-group-form.component.scss

@@ -1,14 +0,0 @@
-@import "variables";
-
-.code-input {
-    display: flex;
-    input {
-        flex: 1;
-        &[readonly] {
-            background-color: $color-grey-1;
-        }
-    }
-    button {
-        margin: 0;
-    }
-}

+ 0 - 1
admin-ui/src/app/catalog/components/create-option-group-form/create-option-group-form.component.ts

@@ -20,7 +20,6 @@ export class CreateOptionGroupFormComponent implements OnInit {
     @Input() productName = '';
     @Input() productId: string;
     optionGroupForm: FormGroup;
-    editCode = false;
     readonly defaultLanguage = getDefaultLanguage();
 
     constructor(private formBuilder: FormBuilder, private dataService: DataService) {}

+ 21 - 11
admin-ui/src/app/shared/components/form-field/form-field-control.directive.ts

@@ -1,19 +1,16 @@
-import { Directive, ElementRef, Optional, Self } from '@angular/core';
-import {
-    FormControl,
-    FormControlDirective,
-    FormControlName,
-    FormGroup,
-    FormGroupDirective,
-    NgControl,
-    NgForm,
-} from '@angular/forms';
+import { Directive, ElementRef, Optional } from '@angular/core';
+import { FormControl, NgControl } from '@angular/forms';
+
+type InputElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
 
 // tslint:disable:directive-selector
 @Directive({ selector: 'input, textarea, select' })
 export class FormFieldControlDirective {
     formControl: FormControl;
-    constructor(@Optional() private formControlName: NgControl) {}
+    constructor(
+        private elementRef: ElementRef<InputElement>,
+        @Optional() private formControlName: NgControl,
+    ) {}
 
     get valid(): boolean {
         return !!this.formControlName && !!this.formControlName.valid;
@@ -22,4 +19,17 @@ export class FormFieldControlDirective {
     get touched(): boolean {
         return !!this.formControlName && !!this.formControlName.touched;
     }
+
+    setReadOnly(value: boolean) {
+        const input = this.elementRef.nativeElement;
+        if (isSelectElement(input)) {
+            input.disabled = value;
+        } else {
+            input.readOnly = value;
+        }
+    }
+}
+
+function isSelectElement(value: InputElement): value is HTMLSelectElement {
+    return value.hasOwnProperty('selectedIndex');
 }

+ 11 - 1
admin-ui/src/app/shared/components/form-field/form-field.component.html

@@ -12,7 +12,17 @@
            role="tooltip"
            [class.invalid]="formFieldControl?.touched && !formFieldControl?.valid"
            class="tooltip tooltip-validation tooltip-sm tooltip-top-left">
-        <ng-content></ng-content>
+        <div class="input-row">
+            <ng-content></ng-content>
+            <button *ngIf="readOnlyToggle"
+                    type="button"
+                    [disabled]="!isReadOnly"
+                    [title]="'common.edit-field' | translate"
+                    class="btn btn-icon btn-sm edit-button"
+                    (click)="setReadOnly(false)">
+                <clr-icon shape="edit"></clr-icon>
+            </button>
+        </div>
         <span class="tooltip-content">
             {{ label }} is required.
         </span>

+ 14 - 0
admin-ui/src/app/shared/components/form-field/form-field.component.scss

@@ -1,3 +1,5 @@
+@import "variables";
+
 :host {
     display: block;
     .form-group > label:nth-of-type(2) {
@@ -11,4 +13,16 @@
     .form-group .tooltip-validation {
         height: initial;
     }
+    .input-row {
+        display: flex;
+        ::ng-deep input {
+            flex: 1;
+            &[readonly] {
+                background-color: $color-grey-2;
+            }
+        }
+        button.edit-button {
+            margin: 0;
+        }
+    }
 }

+ 28 - 2
admin-ui/src/app/shared/components/form-field/form-field.component.ts

@@ -1,4 +1,11 @@
-import { AfterContentInit, ChangeDetectionStrategy, Component, ContentChild, Input } from '@angular/core';
+import {
+    AfterContentInit,
+    ChangeDetectionStrategy,
+    Component,
+    ContentChild,
+    Input,
+    OnInit,
+} from '@angular/core';
 
 import { FormFieldControlDirective } from './form-field-control.directive';
 
@@ -11,9 +18,28 @@ import { FormFieldControlDirective } from './form-field-control.directive';
     templateUrl: './form-field.component.html',
     styleUrls: ['./form-field.component.scss'],
 })
-export class FormFieldComponent {
+export class FormFieldComponent implements OnInit {
     @Input() label: string;
     @Input() for: string;
     @Input() tooltip: string;
+    /**
+     * If set to true, the input will be initially set to "readOnly", and an "edit" button
+     * will be displayed which allows the field to be edited.
+     */
+    @Input() readOnlyToggle = false;
     @ContentChild(FormFieldControlDirective) formFieldControl: FormFieldControlDirective;
+    isReadOnly = false;
+
+    ngOnInit() {
+        if (this.readOnlyToggle) {
+            this.isReadOnly = true;
+            this.setReadOnly(true);
+        }
+        this.isReadOnly = this.readOnlyToggle;
+    }
+
+    setReadOnly(value: boolean) {
+        this.formFieldControl.setReadOnly(value);
+        this.isReadOnly = value;
+    }
 }