src/app/shared/input-inline/input-inline.component.ts
selector | hi-input-inline |
styleUrls | ./input-inline.component.scss |
templateUrl | ./input-inline.component.html |
Properties |
Methods |
|
Inputs |
Outputs |
Accessors |
constructor()
|
blur | |
Type : Function
|
|
Default value : (_) => {}
|
|
disabled | |
Type : boolean
|
|
Default value : false
|
|
editLabel | |
Type : string
|
|
Default value : 'Click to edit'
|
|
errorLabel | |
Type : string
|
|
Default value : 'Invalid input value'
|
|
focus | |
Type : Function
|
|
Default value : (_) => {}
|
|
label | |
Type : string
|
|
Default value : ''
|
|
max | |
Type : number
|
|
Default value : 99999999
|
|
maxlength | |
Type : number
|
|
Default value : 2555
|
|
min | |
Type : number
|
|
Default value : -9999
|
|
minlength | |
Type : number
|
|
Default value : 0
|
|
pattern | |
Type : string
|
|
Default value : null
|
|
required | |
Type : boolean
|
|
Default value : false
|
|
type | |
Type : string
|
|
Default value : 'text'
|
|
value | |
Type : any
|
|
update | |
Type : EventEmitter<string>
|
|
cancel |
cancel()
|
Returns :
void
|
edit | ||||
edit(value)
|
||||
Parameters :
Returns :
void
|
hasError |
hasError()
|
Returns :
boolean
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onBlur | ||||||
onBlur($event: Event)
|
||||||
Parameters :
Returns :
boolean
|
Public registerOnChange | ||||||
registerOnChange(fn: (_: any) => void)
|
||||||
Parameters :
Returns :
void
|
Public registerOnTouched | ||||||
registerOnTouched(fn: () => void)
|
||||||
Parameters :
Returns :
void
|
writeValue | ||||||
writeValue(value: any)
|
||||||
Parameters :
Returns :
void
|
Private _value |
Type : string
|
Default value : ''
|
editing |
Default value : false
|
inputControl |
Type : ElementRef
|
Decorators :
@ViewChild('inputControl', {static: true})
|
Private lastValue |
Type : string
|
Default value : ''
|
Public onChange |
Type : any
|
Default value : Function.prototype
|
Public onTouched |
Type : any
|
Default value : Function.prototype
|
value | ||||||
getvalue()
|
||||||
setvalue(v: any)
|
||||||
Parameters :
Returns :
void
|
import {
Component,
OnInit,
Input,
Output,
ViewChild,
ElementRef,
EventEmitter,
} from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'hi-input-inline',
templateUrl: './input-inline.component.html',
styleUrls: ['./input-inline.component.scss'],
})
export class InputInlineComponent implements ControlValueAccessor, OnInit {
@ViewChild('inputControl', { static: true }) inputControl: ElementRef;
@Output('update') change: EventEmitter<string> = new EventEmitter<string>();
@Input() label = '';
@Input() min = -9999;
@Input() max = 99999999;
@Input() minlength = 0;
@Input() maxlength = 2555;
@Input() type = 'text';
@Input() required = false;
@Input() pattern: string = null;
@Input() errorLabel = 'Invalid input value';
@Input() editLabel = 'Click to edit';
@Input() disabled = false;
editing = false;
private _value = '';
private lastValue = '';
// Required forControlValueAccessor interface
public onChange: any = Function.prototype;
public onTouched: any = Function.prototype;
@Input()
get value(): any {
return this._value;
}
set value(v: any) {
if (v !== this._value) {
this._value = v;
this.onChange(v);
}
}
@Input() focus: Function = (_) => {};
@Input() blur: Function = (_) => {};
public registerOnChange(fn: (_: any) => {}): void {
this.onChange = fn;
}
public registerOnTouched(fn: () => {}): void {
this.onTouched = fn;
}
writeValue(value: any) {
this._value = value;
}
constructor() {}
ngOnInit() {}
hasError() {
const exp = new RegExp(this.pattern);
if (!this.value) {
return this.required;
}
if (this.pattern && !exp.test(this.value)) {
return true;
}
return false;
}
edit(value) {
if (this.disabled) {
return;
}
this.lastValue = value;
this.editing = true;
setTimeout((_) => {
this.inputControl?.nativeElement.focus();
});
}
onBlur($event: Event) {
if (this.hasError()) {
return false;
}
// this.blur();
this.editing = false;
this.change.emit(this.value);
}
cancel() {
this._value = this.lastValue;
this.editing = false;
}
}
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<section>
<mat-form-field
*ngIf="editing"
class="full-width {{ hasError() ? 'error' : '' }}"
>
<input
matInput
#inputControl
[min]="min"
[max]="max"
[minlength]="minlength"
[maxlength]="maxlength"
(focus)="focus($event)"
(blur)="onBlur($event)"
(keyup.enter)="onBlur($event)"
(keyup.escape)="cancel()"
[required]="required"
[name]="value"
[(ngModel)]="value"
[type]="type"
[placeholder]="label"
/>
<mat-hint *ngIf="hasError()" align="start">{{ errorLabel }}</mat-hint>
<mat-hint align="end">press ESC to cancel</mat-hint>
</mat-form-field>
<section *ngIf="!editing">
<div
class="inline-edit {{ hasError() ? 'error' : '' }}"
[matTooltip]="editLabel"
(click)="edit(value)"
(focus)="edit(value)"
tabindex="0"
>
<span *ngIf="value.length">{{ value }}</span>
<span *ngIf="!value.length" class="empty-value">( Empty )</span>
</div>
</section>
</section>
./input-inline.component.scss
.inline-edit {
text-decoration: none;
border-bottom: dashed 1px #009090;
cursor: pointer;
line-height: 2;
margin: 0;
}
.error {
color: #a94442;
}
.empty-value {
color: gray;
font-style: italic;
}
.full-width {
width: 100%;
}