2021-02-12 12:31:12 +01:00
import {
2022-06-09 15:21:43 +02:00
AfterViewInit ,
ChangeDetectorRef ,
2021-03-22 16:10:18 +01:00
Component ,
ElementRef ,
EventEmitter ,
HostListener ,
2021-02-12 12:31:12 +01:00
Input ,
OnChanges ,
OnDestroy ,
OnInit ,
Output ,
SimpleChanges ,
ViewChild
} from "@angular/core" ;
2022-09-23 12:25:08 +02:00
import { AbstractControl , UntypedFormArray , UntypedFormControl , ValidatorFn } from "@angular/forms" ;
2020-11-12 18:57:32 +01:00
import { HelperFunctions } from "../../utils/HelperFunctions.class" ;
2022-03-30 19:47:47 +02:00
import { Subscription } from "rxjs" ;
2022-03-28 00:21:55 +02:00
import { EnvProperties } from "../../utils/properties/env-properties" ;
import { properties } from "../../../../environments/environment" ;
2022-04-13 12:00:40 +02:00
import { ClickEvent } from "../../utils/click/click-outside-or-esc.directive" ;
2019-12-23 16:17:35 +01:00
2022-04-18 10:29:14 +02:00
export type InputType = 'text' | 'URL' | 'logoURL' | 'autocomplete' | 'autocomplete_soft' | 'textarea' | 'select' | 'chips' ;
2022-04-04 10:06:34 +02:00
2019-12-23 16:17:35 +01:00
export interface Option {
icon? : string ,
iconClass? : string ,
value : any ,
2022-04-28 11:13:06 +02:00
label : string ,
2022-07-29 11:24:15 +02:00
tooltip? : string ,
2022-08-05 13:59:08 +02:00
disabled? : boolean ,
hidden? : boolean
2019-12-23 16:17:35 +01:00
}
2022-03-31 15:39:17 +02:00
export interface Placeholder {
label : string ,
static ? : boolean
}
2022-03-30 19:47:47 +02:00
declare var UIkit ;
2022-03-28 00:21:55 +02:00
/ * *
* WARNING ! dashboard - input selector is @deprecated , use input instead
*
2022-04-11 11:27:10 +02:00
* Autocomplete soft allows values that are not listed in options list . In order to work as expected
* avoid providing options with different label and value .
*
2022-03-28 00:21:55 +02:00
* * /
2019-12-23 14:59:56 +01:00
@Component ( {
2022-03-28 00:21:55 +02:00
selector : '[dashboard-input], [input]' ,
2019-12-23 14:59:56 +01:00
template : `
2022-06-01 13:12:18 +02:00
< div * ngIf = "formControl" [ id ] = " id " >
2022-04-04 12:53:26 +02:00
< div class = "input-wrapper" [ class.disabled ] = " formControl.disabled " [ class.opened ] = " opened "
[ class . focused ] = "focused" [ ngClass ] = "inputClass" [ class . hint ] = "hint"
2022-06-08 13:19:40 +02:00
[ class . active ] = "(formAsControl?.value || selectable || formAsArray?.length > 0 || getLabel(formAsControl?.value)) && !focused"
2022-05-27 11:22:04 +02:00
[ class . danger ] = "(formControl.invalid && (formControl.touched || !!searchControl?.touched)) || (!!searchControl?.invalid && !!searchControl?.touched)" >
< div # inputBox class = "input-box" [ class.select ] = " selectable " click - outside - or - esc
2022-04-13 12:00:40 +02:00
[ class . static ] = "placeholderInfo?.static" ( clickOutside ) = "click($event)" >
2022-04-11 11:27:10 +02:00
< div * ngIf = "!placeholderInfo?.static && placeholderInfo.label" class = "placeholder" >
2022-04-04 12:53:26 +02:00
< label > { { placeholderInfo . label } } < sup * ngIf = "required" > * < / sup > < / label >
< / div >
2022-05-27 11:22:04 +02:00
< div class = "uk-flex" [ class.uk - flex - middle ] = " type ! = = ' textarea ' "
2022-12-16 16:19:53 +01:00
[ attr . uk - tooltip ] = "(tooltip && !focused && type !== 'chips' && type !== 'textarea' && (formControl.value || hint || placeholderInfo?.label))?('title: ' + (formControl.value ?getTooltip(formControl.value):(hint?hint:placeholderInfo?.label)) + '; delay: 500; pos: bottom-left'):null" >
2022-04-04 12:53:26 +02:00
< ng - template [ ngIf ] = " type = = = ' text ' | | type = = = ' URL ' | | type = = = ' logoURL ' " >
2022-04-11 11:27:10 +02:00
< input # input class = "input" [ attr.placeholder ] = " placeholderInfo ? .static ? placeholderInfo.label : hint "
2023-01-05 09:53:08 +01:00
[ type ] = "password?'password':'text'" [ formControl ] = "formAsControl" [ class . uk - text - truncate ] = "!focused" >
2022-04-04 12:53:26 +02:00
< / n g - t e m p l a t e >
< ng - template [ ngIf ] = " type = = = ' textarea ' " >
2022-04-11 11:27:10 +02:00
< textarea # textArea class = "input" [ attr.placeholder ] = " placeholderInfo ? .static ? placeholderInfo.label : hint "
2022-04-17 14:25:01 +02:00
[ rows ] = "rows" [ formControl ] = "formAsControl" > < / textarea >
2022-04-04 12:53:26 +02:00
< / n g - t e m p l a t e >
< ng - template [ ngIf ] = " type = = = ' select ' " >
2022-04-15 10:08:12 +02:00
< ng - container * ngIf = "placeholderInfo?.static" >
2022-05-27 11:22:04 +02:00
< div * ngIf = "!getLabel(formControl.value)"
2022-07-04 20:43:50 +02:00
class = "input placeholder uk-width-expand uk-text-truncate" > { { placeholderInfo . label } } < / div >
2022-05-27 11:22:04 +02:00
< div * ngIf = "getLabel(formControl.value)"
2022-07-04 20:38:27 +02:00
class = "input uk-width-expand uk-text-truncate" > { { getLabel ( formControl . value ) } } < / div >
2022-04-15 10:08:12 +02:00
< / n g - c o n t a i n e r >
< ng - container * ngIf = "!placeholderInfo?.static" >
2022-07-04 20:38:27 +02:00
< div * ngIf = "!getLabel(formControl.value)" class = "input uk-width-expand uk-text-truncate" > { { noValueSelected } } < / div >
2022-05-27 11:22:04 +02:00
< div * ngIf = "getLabel(formControl.value)"
2022-07-04 20:38:27 +02:00
class = "input uk-width-expand uk-text-truncate" > { { getLabel ( formControl . value ) } } < / div >
2022-04-15 10:08:12 +02:00
< / n g - c o n t a i n e r >
2022-04-04 12:53:26 +02:00
< / n g - t e m p l a t e >
< ng - template [ ngIf ] = " type = = = ' autocomplete ' " >
2022-04-11 11:27:10 +02:00
< input * ngIf = "focused" [ attr.placeholder ] = " placeholderInfo ? .static ? placeholderInfo.label : hint "
2022-04-09 15:19:18 +02:00
# searchInput class = "input" [ formControl ] = "searchControl" [ class . uk - text - truncate ] = "!focused" >
2022-06-08 13:19:40 +02:00
< div * ngIf = "!focused && !selectable" class = "input uk-text-truncate" > { { getLabel ( formAsControl . value ) } } < / div >
< ng - container * ngIf = "!focused && selectable" >
< div * ngIf = "!getLabel(formControl.value)" class = "input uk-text-truncate" > { { noValueSelected } } < / div >
< div * ngIf = "getLabel(formControl.value)" class = "input uk-text-truncate" > { { getLabel ( formControl . value ) } } < / div >
< / n g - c o n t a i n e r >
2022-04-04 12:53:26 +02:00
< / n g - t e m p l a t e >
2022-04-11 11:27:10 +02:00
< ng - template [ ngIf ] = " type = = = ' autocomplete_soft ' " >
< input # input class = "input" [ attr.placeholder ] = " placeholderInfo ? .static ? placeholderInfo.label : hint "
[ formControl ] = "formAsControl" [ class . uk - text - truncate ] = "!focused" >
< / n g - t e m p l a t e >
2022-04-04 12:53:26 +02:00
< ng - template [ ngIf ] = " type = = = ' chips ' " >
< div class = "uk-grid uk-grid-small uk-grid-row-collapse uk-width-expand" uk - grid >
2022-04-17 14:25:01 +02:00
< div * ngFor = "let chip of formAsArray.controls; let i=index" [ class.uk - hidden ] = " ! focused & & i > 0 "
class = "chip" >
2022-05-27 11:22:04 +02:00
< div class = "uk-label uk-label-small uk-flex uk-flex-middle"
2022-06-06 16:16:51 +02:00
[ attr . uk - tooltip ] = "(tooltip)?('title: ' + getLabel(chip.value) + '; delay: 500; pos: bottom-left'):null" >
2022-04-04 12:53:26 +02:00
< span class = "uk-text-truncate uk-width-expand" > { { getLabel ( chip . value ) } } < / span >
2022-07-02 13:43:18 +02:00
< icon * ngIf = "focused" ( click ) = " remove ( i , $ event ) " class = "uk-link-text uk-margin-small-left clickable" [ flex ] = " true "
2022-04-04 12:53:26 +02:00
name = "close" ratio = "0.7" > < / icon >
< / div >
< / div >
2022-04-17 14:25:01 +02:00
< div * ngIf = "searchControl && (focused || formAsArray.length === 0)"
class = "uk-width-small uk-flex uk-flex-column uk-flex-center" >
2022-04-04 12:53:26 +02:00
< input # searchInput class = "input" [ class.search ] = " searchControl.value "
2022-04-11 11:27:10 +02:00
[ attr . placeholder ] = "placeholderInfo?.static?placeholderInfo.label:hint"
2022-04-09 15:19:18 +02:00
[ formControl ] = "searchControl" [ class . uk - text - truncate ] = "!focused" >
2022-04-04 12:53:26 +02:00
< / div >
2022-04-17 14:25:01 +02:00
< div * ngIf = "!focused && formAsArray.length > 1"
class = "uk-width-expand uk-flex uk-flex-column uk-flex-center more" >
2022-04-11 11:27:10 +02:00
+ { { ( formAsArray . length - 1 ) } } more
< / div >
2022-03-31 15:39:17 +02:00
< / div >
< / n g - t e m p l a t e >
2022-06-09 15:21:43 +02:00
< div * ngIf = "(formControl.disabled && disabledIcon) || icon || (selectable && selectArrow) || type === 'autocomplete' || searchable"
class = "uk-margin-small-left icon" >
2022-04-12 16:20:51 +02:00
< icon * ngIf = "formControl.disabled && disabledIcon" [ name ] = " disabledIcon " [ flex ] = " true " > < / icon >
2022-04-04 12:53:26 +02:00
< ng - template [ ngIf ] = " formControl.enabled " >
2022-05-27 11:22:04 +02:00
< icon * ngIf = "!searchControl?.value && icon" [ name ] = " icon " [ flex ] = " true " > < / icon >
2022-06-08 13:19:40 +02:00
< icon * ngIf = "!icon && selectable && selectArrow" [ name ] = " selectArrow " [ flex ] = " true " > < / icon >
2022-05-27 11:22:04 +02:00
< button * ngIf = "!!searchControl?.value && type === 'autocomplete'" class = "uk-close uk-icon"
2022-04-17 14:25:01 +02:00
( click ) = "resetSearch($event)" >
< icon [ flex ] = " true " name = "close" > < / icon >
2022-04-17 00:42:10 +02:00
< / button >
2022-06-09 15:21:43 +02:00
< button * ngIf = "!!formControl?.value && searchable" class = "uk-close uk-icon" ( click ) = " resetValue ( $ event ) " >
< icon [ flex ] = " true " name = "close" > < / icon >
< / button >
2022-04-04 12:53:26 +02:00
< / n g - t e m p l a t e >
< / div >
< / div >
< div class = "tools" >
< ng - content select = "[tools]" > < / n g - c o n t e n t >
2022-03-30 19:47:47 +02:00
< / div >
2022-03-31 15:39:17 +02:00
< / div >
2022-03-28 00:21:55 +02:00
< / div >
2022-04-04 12:53:26 +02:00
< div class = "options uk-dropdown" * ngIf = "filteredOptions && filteredOptions.length > 0 && opened" # optionBox
2022-04-06 11:53:26 +02:00
uk - dropdown = "pos: bottom-justify; mode: none; offset: 15; boundary-align: true;" [ attr . boundary ] = "'#' + id" >
2022-04-04 12:53:26 +02:00
< ul class = "uk-nav uk-dropdown-nav" >
2022-08-05 13:59:08 +02:00
< li * ngFor = "let option of filteredOptions; let i=index" [ class.uk - hidden ] = " option.hidden " [ class.uk - active ] = " ( formControl.value = = = option.value ) | | selectedIndex = = = i " >
2022-04-28 11:13:06 +02:00
< a ( click ) = " selectOption ( option , $ event ) "
2022-06-06 15:34:46 +02:00
[ class ] = "option.disabled ? 'uk-disabled uk-text-muted' : ''" >
2022-07-29 11:24:15 +02:00
< span [ attr.uk - tooltip ] = " ( tooltip ) ? ( ' title : ' + ( option.tooltip ? option.tooltip : option.label ) + ' ; delay : 500 ; pos : bottom - left ' ) : null " > { { option . label } } < / span >
2022-06-06 15:34:46 +02:00
< / a >
2022-04-04 12:53:26 +02:00
< / li >
< / ul >
< / div >
2022-03-30 19:47:47 +02:00
< / div >
2022-06-01 13:12:18 +02:00
< span * ngIf = "formControl?.invalid && formControl?.touched" class = "uk-text-danger" >
2022-03-28 00:21:55 +02:00
< span * ngIf = "formControl.errors.error" > { { formControl . errors . error } } < / span >
2022-03-31 15:39:17 +02:00
< span * ngIf = "type === 'URL' || type === 'logoURL'" > Please provide a valid URL ( e . g . https : //example.com)</span>
2022-03-28 00:21:55 +02:00
< / span >
< span class = "uk-text-danger uk-text-small" >
< ng - content select = "[error]" > < / n g - c o n t e n t >
< / span >
2022-06-01 13:12:18 +02:00
< span * ngIf = "formControl?.valid" class = "uk-text-warning uk-text-small" >
2022-03-28 00:21:55 +02:00
< ng - content select = "[warning]" > < / n g - c o n t e n t >
< span * ngIf = "!secure" >
< span class = "uk-text-bold" > Note : < / span > Prefer urls like "<span class=" uk - text - bold ">https://</span>example.com/my-secure-image.png"
instead of "<span class=" uk - text - bold ">http://</span>example.com/my-image.png" .
< span class = "uk-text-bold" > Browsers may not load non secure content . < / span >
< / span >
< / span >
< span class = "uk-text-small" >
< ng - content select = "[note]" > < / n g - c o n t e n t >
< / span >
2022-03-31 15:39:17 +02:00
`
2019-12-23 14:59:56 +01:00
} )
2022-03-28 00:21:55 +02:00
export class InputComponent implements OnInit , OnDestroy , AfterViewInit , OnChanges {
2022-04-04 12:53:26 +02:00
private static INPUT_COUNTER : number = 0 ;
2022-03-31 15:39:17 +02:00
/** Deprecated options*/
2022-03-28 00:21:55 +02:00
/** @deprecated */
2019-12-23 14:59:56 +01:00
@Input ( 'label' ) label : string ;
2022-03-28 00:21:55 +02:00
/** @deprecated */
2020-10-19 11:06:23 +02:00
@Input ( ) extraLeft : boolean = true ;
2022-03-28 00:21:55 +02:00
/** @deprecated */
2021-01-21 16:15:53 +01:00
@Input ( ) gridSmall : boolean = false ;
2022-03-28 00:21:55 +02:00
/** @deprecated */
2020-10-19 17:05:16 +02:00
@Input ( ) hideControl : boolean = false ;
2022-03-28 00:21:55 +02:00
/** @deprecated */
2021-02-12 12:31:12 +01:00
@Input ( ) flex : 'middle' | 'top' | 'bottom' = 'middle' ;
2022-03-28 00:21:55 +02:00
/** @deprecated */
2020-11-01 16:41:02 +01:00
@Input ( ) iconLeft : boolean = false ;
2022-03-31 15:39:17 +02:00
/** @deprecated */
2021-01-28 17:33:16 +01:00
@Input ( ) removable : boolean = true ;
2022-03-31 15:39:17 +02:00
/** @deprecated */
2021-02-17 19:44:02 +01:00
@Input ( ) smallChip : boolean = false ;
2022-03-31 15:39:17 +02:00
/** @deprecated */
2021-02-17 19:44:02 +01:00
@Input ( ) panelWidth : number = 300 ;
2022-03-31 15:39:17 +02:00
/** @deprecated */
2021-02-17 19:44:02 +01:00
@Input ( ) panelClass : string = null ;
2022-03-31 15:39:17 +02:00
/** Basic information */
@Input ( 'formInput' ) formControl : AbstractControl ;
2022-04-04 10:06:34 +02:00
@Input ( 'type' ) type : InputType = 'text' ;
2023-01-05 09:53:08 +01:00
@Input ( ) password : boolean = false ;
2022-04-04 10:06:34 +02:00
@Input ( ) validators : ValidatorFn [ ] | ValidatorFn ;
@Input ( ) disabled : boolean = false ;
2022-04-12 16:20:51 +02:00
@Input ( ) disabledIcon : string = 'lock' ;
2022-03-31 15:39:17 +02:00
@Input ( ) value : any | any [ ] ;
@Output ( ) valueChange = new EventEmitter < any | any [ ] > ( ) ;
2022-04-17 00:42:10 +02:00
@Input ( ) hint : string ;
2022-06-06 11:22:01 +02:00
@Input ( ) tooltip : boolean = false ;
2022-06-09 15:21:43 +02:00
@Input ( ) searchable : boolean = false ;
2022-03-31 15:39:17 +02:00
/** Text */
@ViewChild ( 'input' ) input : ElementRef ;
/** Textarea options */
@ViewChild ( 'textArea' ) textArea : ElementRef ;
@Input ( 'rows' ) rows : number = 3 ;
/** Select | Autocomplete | chips available options */
2022-04-04 10:06:34 +02:00
@Input ( ) selectArrow : string = 'arrow_drop_down' ;
2022-04-04 15:44:00 +02:00
@Input ( ) selectedIndex : number = 0 ;
2022-05-27 11:22:04 +02:00
@Input ( ) selectable : boolean = false ;
2022-06-08 13:19:40 +02:00
@Input ( ) noValueSelected : string = 'No option selected' ;
2022-03-31 15:39:17 +02:00
/** Chips && Autocomplete*/
public filteredOptions : Option [ ] = [ ] ;
2022-09-23 12:25:08 +02:00
public searchControl : UntypedFormControl ;
2022-03-31 15:39:17 +02:00
/** Use modifier's class(es) to change view of your Input */
@Input ( ) inputClass : string = 'inner' ;
/** Icon on the input */
@Input ( ) icon : string = null ;
/** Chip options */
@Input ( ) addExtraChips : boolean = false ;
2021-02-24 17:53:31 +01:00
@Input ( ) showOptionsOnEmpty : boolean = true ;
2021-02-12 12:31:12 +01:00
@Output ( ) focusEmitter : EventEmitter < boolean > = new EventEmitter < boolean > ( ) ;
2021-03-03 19:04:53 +01:00
/** LogoUrl information */
public secure : boolean = true ;
2021-02-12 12:31:12 +01:00
/** Internal basic information */
2022-04-04 12:53:26 +02:00
public id : string ;
2022-03-31 15:39:17 +02:00
public placeholderInfo : Placeholder = { label : '' , static : true } ;
2020-06-05 16:48:12 +02:00
public required : boolean = false ;
2022-03-28 00:21:55 +02:00
public focused : boolean = false ;
public opened : boolean = false ;
public properties : EnvProperties = properties ;
2019-12-23 14:59:56 +01:00
private initValue : any ;
2022-04-04 15:44:00 +02:00
private optionsArray : Option [ ] = [ ] ;
2022-06-20 12:11:21 +02:00
private optionsBreakpoint : number = 6 ;
2022-03-28 00:21:55 +02:00
private subscriptions : any [ ] = [ ] ;
@ViewChild ( 'inputBox' ) inputBox : ElementRef ;
@ViewChild ( 'optionBox' ) optionBox : ElementRef ;
2021-02-12 12:31:12 +01:00
@ViewChild ( 'searchInput' ) searchInput : ElementRef ;
2020-10-19 11:06:23 +02:00
2022-03-31 15:39:17 +02:00
@Input ( )
set placeholder ( placeholder : string | Placeholder ) {
2022-04-04 10:06:34 +02:00
if ( typeof placeholder === 'string' ) {
2022-03-31 15:39:17 +02:00
this . placeholderInfo = { label : placeholder , static : false } ;
} else {
2022-04-04 10:06:34 +02:00
if ( placeholder . static && ( this . type === 'autocomplete' || this . type === 'chips' || this . hint ) ) {
2022-03-31 15:39:17 +02:00
placeholder . static = false ;
console . debug ( 'Static placeholder is not available in this type of input and if hint is available.' ) ;
}
this . placeholderInfo = placeholder ;
}
}
2022-04-04 15:44:00 +02:00
@Input ( )
2022-06-01 15:28:44 +02:00
set options ( options : ( Option | string | number ) [ ] ) {
2022-04-04 15:44:00 +02:00
this . optionsArray = options . map ( option = > {
2022-06-01 15:28:44 +02:00
if ( typeof option === 'string' || typeof option === 'number' ) {
2022-04-04 15:44:00 +02:00
return {
2022-06-01 15:28:44 +02:00
label : option.toString ( ) ,
2022-04-04 15:44:00 +02:00
value : option
2022-04-17 00:42:10 +02:00
} ;
2022-04-04 15:44:00 +02:00
} else {
2022-04-17 00:42:10 +02:00
return option ;
2022-04-04 15:44:00 +02:00
}
} ) ;
2022-06-06 16:16:51 +02:00
if ( ! this . tooltip ) {
this . tooltip = this . optionsArray . length > 0 ;
}
2022-05-27 11:22:04 +02:00
if ( this . type === "select" ) {
2022-06-20 12:11:21 +02:00
if ( this . optionsArray . length > this . optionsBreakpoint ) {
2022-05-27 11:22:04 +02:00
this . type = 'autocomplete' ;
this . showOptionsOnEmpty = true ;
this . icon = this . selectArrow ;
}
this . selectable = true ;
}
2022-04-04 15:44:00 +02:00
}
2022-04-04 10:06:34 +02:00
constructor ( private elementRef : ElementRef , private cdr : ChangeDetectorRef ) {
2022-03-28 00:21:55 +02:00
if ( elementRef . nativeElement . hasAttribute ( 'dashboard-input' ) && this . properties . environment === "development" ) {
console . warn ( "'dashboard-input' selector is deprecated; use 'input' instead." ) ;
}
2021-02-12 12:31:12 +01:00
}
2022-04-17 14:25:01 +02:00
@HostListener ( 'window:keydown.arrowUp' , [ '$event' ] )
arrowUp ( event : KeyboardEvent ) {
if ( this . opened ) {
event . preventDefault ( ) ;
if ( this . selectedIndex > 0 ) {
this . selectedIndex -- ;
this . optionBox . nativeElement . scrollBy ( 0 , - 34 ) ;
}
}
}
@HostListener ( 'window:keydown.arrowDown' , [ '$event' ] )
arrowDown ( event : KeyboardEvent ) {
if ( this . opened ) {
event . preventDefault ( ) ;
if ( this . selectedIndex < ( this . filteredOptions . length - 1 ) ) {
this . selectedIndex ++ ;
this . optionBox . nativeElement . scrollBy ( 0 , 34 ) ;
}
}
}
@HostListener ( 'window:keydown.enter' , [ '$event' ] )
enter ( event : KeyboardEvent ) {
2022-06-28 20:13:40 +02:00
if ( this . opened && this . optionBox ) {
2022-04-17 14:25:01 +02:00
event . preventDefault ( ) ;
if ( this . filteredOptions [ this . selectedIndex ] ) {
this . selectOption ( this . filteredOptions [ this . selectedIndex ] , event ) ;
2022-04-04 15:44:00 +02:00
}
2022-06-09 14:25:24 +02:00
this . open ( false ) ;
event . stopPropagation ( ) ;
} else {
this . focus ( false , event ) ;
2022-04-04 15:44:00 +02:00
}
}
2022-04-13 12:00:40 +02:00
click ( event : ClickEvent ) {
this . focus ( ! event . clicked , event ) ;
2019-12-23 14:59:56 +01:00
}
2020-10-19 11:06:23 +02:00
2022-03-28 00:21:55 +02:00
ngOnInit() {
2022-04-04 12:53:26 +02:00
InputComponent . INPUT_COUNTER ++ ;
this . id = 'input-' + InputComponent . INPUT_COUNTER ;
2022-03-30 19:47:47 +02:00
if ( ! this . formControl ) {
if ( Array . isArray ( this . value ) ) {
2022-09-23 12:25:08 +02:00
this . formControl = new UntypedFormArray ( [ ] ) ;
2022-03-28 00:21:55 +02:00
this . value . forEach ( value = > {
2022-09-23 12:25:08 +02:00
this . formAsArray . push ( new UntypedFormControl ( value , this . validators ) ) ;
2022-03-28 00:21:55 +02:00
} ) ;
} else {
2022-09-23 12:25:08 +02:00
this . formControl = new UntypedFormControl ( this . value ) ;
2022-03-28 00:21:55 +02:00
this . formControl . setValidators ( this . validators ) ;
}
2022-03-30 19:47:47 +02:00
if ( this . disabled ) {
2022-03-28 00:21:55 +02:00
this . formControl . disable ( ) ;
}
}
}
2022-02-08 10:52:11 +01:00
ngAfterViewInit() {
2020-10-19 11:06:23 +02:00
this . reset ( ) ;
}
ngOnChanges ( changes : SimpleChanges ) {
2022-04-17 14:25:01 +02:00
if ( this . formControl ) {
2022-04-05 14:33:38 +02:00
if ( changes . value ) {
this . formControl . setValue ( this . value ) ;
}
if ( changes . formControl || changes . validators || changes . options ) {
this . reset ( ) ;
}
2022-04-17 14:25:01 +02:00
if ( changes . disabled ) {
if ( this . disabled ) {
2022-04-12 16:20:51 +02:00
this . formControl . disable ( ) ;
} else {
this . formControl . enable ( ) ;
}
}
2020-10-19 11:06:23 +02:00
}
}
2022-03-30 19:47:47 +02:00
ngOnDestroy ( ) : void {
this . unsubscribe ( ) ;
}
2022-09-23 12:25:08 +02:00
get formAsControl ( ) : UntypedFormControl {
if ( this . formControl instanceof UntypedFormControl ) {
2022-03-28 00:21:55 +02:00
return this . formControl ;
} else {
return null ;
}
}
2022-09-23 12:25:08 +02:00
get formAsArray ( ) : UntypedFormArray {
if ( this . formControl instanceof UntypedFormArray ) {
2022-03-28 00:21:55 +02:00
return this . formControl ;
} else {
return null ;
}
2021-01-28 17:33:16 +01:00
}
2020-10-19 11:06:23 +02:00
reset() {
2021-03-03 19:04:53 +01:00
this . secure = true ;
2020-10-19 11:06:23 +02:00
this . unsubscribe ( ) ;
2019-12-23 14:59:56 +01:00
this . initValue = HelperFunctions . copy ( this . formControl . value ) ;
2022-03-28 00:21:55 +02:00
if ( this . type === 'logoURL' ) {
2021-03-03 19:04:53 +01:00
this . secure = ( ! this . initValue || this . initValue . includes ( 'https://' ) ) ;
}
2022-04-04 15:44:00 +02:00
if ( this . optionsArray ) {
2022-03-30 19:47:47 +02:00
this . filteredOptions = this . filter ( '' ) ;
2022-04-06 09:35:10 +02:00
this . cdr . detectChanges ( ) ;
2022-03-30 19:47:47 +02:00
}
2021-03-22 16:10:18 +01:00
if ( this . type === 'chips' || this . type === 'autocomplete' ) {
2022-04-04 10:06:34 +02:00
if ( ! this . searchControl ) {
2022-09-23 12:25:08 +02:00
this . searchControl = new UntypedFormControl ( '' , this . validators ) ;
2022-04-04 10:06:34 +02:00
}
2022-03-30 19:47:47 +02:00
this . subscriptions . push ( this . searchControl . valueChanges . subscribe ( value = > {
this . filteredOptions = this . filter ( value ) ;
2022-04-06 09:35:10 +02:00
this . cdr . detectChanges ( ) ;
2022-03-30 19:47:47 +02:00
if ( this . focused ) {
this . open ( true ) ;
2021-03-22 16:10:18 +01:00
setTimeout ( ( ) = > {
this . searchInput . nativeElement . focus ( ) ;
this . searchInput . nativeElement . value = value ;
2022-03-28 00:21:55 +02:00
} , 0 ) ;
2022-03-30 19:47:47 +02:00
}
} ) ) ;
2021-01-28 17:33:16 +01:00
}
2022-04-05 14:33:38 +02:00
if ( this . formControl . validator ) {
2020-06-05 16:48:12 +02:00
let validator = this . formControl . validator ( { } as AbstractControl ) ;
this . required = ( validator && validator . required ) ;
}
2020-10-19 11:06:23 +02:00
this . subscriptions . push ( this . formControl . valueChanges . subscribe ( value = > {
2022-04-17 14:25:01 +02:00
if ( this . formControl . enabled ) {
2022-04-12 16:20:51 +02:00
value = ( value === '' ) ? null : value ;
if ( this . type === 'logoURL' ) {
this . secure = ( ! value || value . includes ( 'https://' ) ) ;
}
if ( this . initValue === value || ( this . initValue === '' && value === null ) ) {
this . formControl . markAsPristine ( ) ;
} else {
this . formControl . markAsDirty ( ) ;
}
if ( this . type === 'autocomplete_soft' ) {
this . filteredOptions = this . filter ( value ) ;
this . cdr . detectChanges ( ) ;
if ( this . focused ) {
this . open ( true ) ;
}
}
2022-04-17 14:25:01 +02:00
if ( ( this . value && value && this . value !== value ) || ( ! this . value && value ) || this . value && ! value ) {
2022-04-12 16:20:51 +02:00
this . valueChange . emit ( this . formControl . value ) ;
2022-04-11 11:27:10 +02:00
}
}
2020-10-19 11:06:23 +02:00
} ) ) ;
2022-03-28 00:21:55 +02:00
if ( this . input ) {
2022-02-08 10:52:11 +01:00
this . input . nativeElement . disabled = this . formControl . disabled ;
}
2020-10-19 11:06:23 +02:00
}
unsubscribe() {
this . subscriptions . forEach ( subscription = > {
2021-02-12 12:31:12 +01:00
if ( subscription instanceof Subscription ) {
2020-10-19 11:06:23 +02:00
subscription . unsubscribe ( ) ;
}
2019-12-23 14:59:56 +01:00
} ) ;
}
2022-04-17 14:25:01 +02:00
2022-04-04 10:06:34 +02:00
remove ( index : number , event ) {
2022-04-17 14:25:01 +02:00
if ( this . focused ) {
2022-04-17 00:42:10 +02:00
this . formAsArray . removeAt ( index ) ;
this . formAsArray . markAsDirty ( ) ;
this . focus ( true ) ;
this . searchControl . setValue ( '' ) ;
event . stopPropagation ( ) ;
}
2021-01-28 17:33:16 +01:00
}
private filter ( value : string ) : Option [ ] {
2022-08-05 13:59:08 +02:00
let options = this . optionsArray . filter ( option = > ! option . hidden ) ;
2022-03-28 00:21:55 +02:00
if ( this . type === "chips" ) {
options = options . filter ( option = > ! this . formAsArray . value . find ( value = > HelperFunctions . equals ( option . value , value ) ) ) ;
2021-03-19 15:23:47 +01:00
}
if ( ( ! value || value . length == 0 ) ) {
2022-04-04 15:44:00 +02:00
this . selectedIndex = 0 ;
2022-03-28 00:21:55 +02:00
return ( this . showOptionsOnEmpty ) ? options : [ ] ;
2021-01-28 17:33:16 +01:00
}
const filterValue = value . toString ( ) . toLowerCase ( ) ;
2022-04-04 15:44:00 +02:00
options = options . filter ( option = > option . label . toLowerCase ( ) . indexOf ( filterValue ) != - 1 ) ;
this . selectedIndex = options . findIndex ( option = > option . value === this . formControl . value ) ;
2022-04-17 14:25:01 +02:00
if ( this . selectedIndex === - 1 ) {
2022-04-04 15:44:00 +02:00
this . selectedIndex = 0 ;
}
return options ;
2021-01-28 17:33:16 +01:00
}
2021-02-12 12:31:12 +01:00
2022-04-04 10:06:34 +02:00
add ( event ) {
2022-03-30 19:47:47 +02:00
if ( this . addExtraChips && this . searchControl . value && this . searchControl . valid ) {
2022-06-28 20:13:40 +02:00
if ( event && event . stopPropagation ) {
2022-04-04 10:06:34 +02:00
event . stopPropagation ( ) ;
}
2022-09-23 12:25:08 +02:00
this . formAsArray . push ( new UntypedFormControl ( this . searchControl . value , this . validators ) ) ;
2021-02-12 12:31:12 +01:00
this . formAsArray . markAsDirty ( ) ;
}
2022-04-11 11:27:10 +02:00
this . searchControl . setValue ( '' ) ;
2021-02-12 12:31:12 +01:00
}
2022-06-08 13:19:40 +02:00
getLabel ( value : any ) : string {
2022-05-11 09:17:06 +02:00
let option = this . optionsArray . find ( option = > HelperFunctions . equals ( option . value , value ) ) ;
2022-04-04 10:06:34 +02:00
return ( option ) ? option . label : ( value ) ;
2021-02-12 12:31:12 +01:00
}
2022-08-02 15:49:09 +02:00
getTooltip ( value : any ) : string {
let option = this . optionsArray . find ( option = > HelperFunctions . equals ( option . value , value ) ) ;
return ( option ) ? ( option . tooltip ? option.tooltip : option.label ) : ( value ) ;
}
2021-03-19 15:23:47 +01:00
2022-04-04 10:06:34 +02:00
focus ( value : boolean , event = null ) {
if ( this . focused ) {
2022-03-30 19:47:47 +02:00
this . formControl . markAsTouched ( ) ;
}
this . focused = value ;
2022-04-07 17:17:52 +02:00
this . cdr . detectChanges ( ) ;
2022-03-30 19:47:47 +02:00
if ( this . focused ) {
if ( this . input ) {
this . input . nativeElement . focus ( ) ;
} else if ( this . textArea ) {
this . textArea . nativeElement . focus ( ) ;
} else if ( this . searchInput ) {
this . searchInput . nativeElement . focus ( ) ;
}
2022-05-27 11:22:04 +02:00
if ( this . selectArrow ) {
2022-03-30 19:47:47 +02:00
this . open ( ! this . opened ) ;
2022-05-27 11:22:04 +02:00
} else if ( this . type !== 'autocomplete' || this . showOptionsOnEmpty || ! this . formControl . value ) {
2022-03-30 19:47:47 +02:00
this . open ( true ) ;
}
} else {
this . open ( false ) ;
2022-04-13 12:00:40 +02:00
if ( this . input ) {
this . input . nativeElement . blur ( ) ;
} else if ( this . textArea ) {
this . textArea . nativeElement . blur ( ) ;
} else if ( this . searchInput ) {
this . searchInput . nativeElement . blur ( ) ;
}
2022-03-30 19:47:47 +02:00
if ( this . searchControl ) {
2022-04-04 10:06:34 +02:00
this . add ( event ) ;
2022-03-30 19:47:47 +02:00
}
}
this . focusEmitter . emit ( this . focused ) ;
}
2022-03-28 00:21:55 +02:00
open ( value : boolean ) {
this . opened = value && this . formControl . enabled ;
2022-04-04 10:06:34 +02:00
this . cdr . detectChanges ( ) ;
2022-05-27 11:22:04 +02:00
if ( this . optionBox && this . opened ) {
this . selectedIndex = this . filteredOptions . findIndex ( option = > option . value === this . formControl . value ) ;
2022-06-09 14:25:24 +02:00
if ( this . selectedIndex === - 1 && this . type !== 'autocomplete_soft' ) {
2022-05-27 11:22:04 +02:00
this . selectedIndex = 0 ;
}
UIkit . dropdown ( this . optionBox . nativeElement ) . show ( ) ;
} else {
if ( this . optionBox ) {
2022-04-04 10:06:34 +02:00
UIkit . dropdown ( this . optionBox . nativeElement ) . hide ( ) ;
2022-05-30 14:42:54 +02:00
this . focused = false ;
2022-03-30 19:47:47 +02:00
}
2022-04-04 10:06:34 +02:00
}
2022-03-28 00:21:55 +02:00
}
2021-03-22 16:10:18 +01:00
resetSearch ( event : any ) {
2021-03-19 15:23:47 +01:00
event . stopPropagation ( ) ;
2022-03-30 19:47:47 +02:00
this . searchControl . setValue ( '' ) ;
2022-06-09 15:21:43 +02:00
this . focus ( true , event ) ;
}
resetValue ( event : any ) {
event . stopPropagation ( ) ;
this . formControl . setValue ( '' ) ;
this . focus ( true , event ) ;
2021-03-19 15:23:47 +01:00
}
2022-03-28 00:21:55 +02:00
2022-03-30 19:47:47 +02:00
selectOption ( option : Option , event ) {
2022-04-04 10:06:34 +02:00
if ( this . formControl . enabled ) {
2022-03-30 19:47:47 +02:00
if ( this . formAsControl ) {
this . formAsControl . setValue ( option . value ) ;
} else if ( this . formAsArray ) {
2022-09-23 12:25:08 +02:00
this . formAsArray . push ( new UntypedFormControl ( option . value ) ) ;
2022-03-30 19:47:47 +02:00
this . formAsArray . markAsDirty ( ) ;
event . stopPropagation ( ) ;
this . focus ( true ) ;
this . searchControl . setValue ( '' ) ;
}
2022-03-28 00:21:55 +02:00
}
}
2019-12-23 14:59:56 +01:00
}