File

projects/congarevenuecloud/elements/src/lib/input-field/input-field.component.ts

Description

The Input field component displays the field values as a radio button, checkbox, dropdown, a text area or a label value, depending upon the field type.

Preview

Usage

Example :
import { InputFieldModule } from '@congarevenuecloud/elements';

@NgModule({
imports: [InputFieldModule, ...]
})
export class AppModule {}
Example :
// Basic Usage
```typescript
<apt-input-field
            [(ngModel)]="myModel"
            [field]="fieldApiName"
            [entity]="entityApiName"
></apt-input-field>
Example :
// All inputs and outputs
```typescript
<apt-input-field
            [(ngModel)]="myModel"
            (ngModelChange)="handleChange($event)"
            [field]="fieldApiName"
            [entity]="entityApiName"
            [label]="label"
            [readonly]="isReadOnly"
            [allowEmpty]="allowEmpty"
            [disabledValues]="disabledValues"
            [hiddenValues]="hiddenValues"
            [inline]="isInline"
            [inputSize]="'small'"
            [rows]="2"
            [placeholder]="myPlaceholder"
            [required]="true"
            [errorMsg]="errorMessage"
            [showLabel]="true"
            [labelClass]="labelClass"
            [filterValues]="filterValues"
            [hideOptions]="true"
            [hide]="true"
            [defaultValue]="true"
            [enableValues]="values"
            [lookupOptions]="lookupOptions"
></apt-input-field>

Implements

ControlValueAccessor OnChanges OnDestroy

Metadata

Index

Inputs

Constructor

constructor(translateService: TranslateService, aobjectService: AObjectService, cdr: ChangeDetectorRef, metadataService: MetadataService, apiService: ApiService)
Parameters :
Name Type Optional
translateService TranslateService No
aobjectService AObjectService No
cdr ChangeDetectorRef No
metadataService MetadataService No
apiService ApiService No

Inputs

allowClearableLookups
Type : boolean
Default value : true

Boolean specifies whether the lookup values in the select component can be cleared. When set to true, the clear button will be visible, allowing users to clear the selected values. When set to false, the clear button won't show, preventing users from clearing the selected values. Default value is true.

allowEmpty
Type : boolean
Default value : false

Flag to allow this input to be empty.

asterisk
Type : boolean
Default value : true

Flag to show the asterisk on a field.

defaultValue
Type : boolean

Boolean value when set to true will populate the incoming field with default value

disabledValues
Type : Set<string>
Default value : new Set<string>()

Set of disabled values.

displayFieldType
Type : "radio" | "dropdown"

The property is responsible to override the input field as type 'radio' for metadata type boolean and 'dropdown' for the metadata type multipicklist.

enableValues
Type : Array<string>

List of enabled values for multipicklist.

entity
Type : AObject

Represents an AObject instance

errorMsg
Type : string

Property to show error message

field
Type : string

Represents the field name type of string for the AObject.

fieldType
Type : string

The property overrides the default type of the field to render the corresponding input field.

filterValues
Type : Array<string>

The list of values to be set in the picklist.

hiddenValues
Type : Set<string>
Default value : new Set<string>()

Set of hidden values.

hide
Type : boolean
Default value : false

Boolean value to show or hide the component.

hideOptions
Type : boolean
Default value : false

Boolean value to show default picklist values or not.

inline
Type : boolean
Default value : false

Flag to set this input as inline.

inputSize
Type : "normal" | "small"
Default value : 'normal'

Flag to set the size of the input. By default the value is 'normal'. When set to 'small' the input will be set with '.form-control-sm' bootstrap class.

label
Type : string

The override default values for the input Label.

labelClass
Type : string

To override the default styling of input field label, set the bootstrap classes of type string. Ex: 'mb-1'

lookupObjectName
Type : string

Name of the lookupObject of type string.

lookupOptions
Type : LookupOptions

Object to set primary text field, secondary text field, thumbnail field, conditions, filters etc

minVal
Type : number
Default value : 1

set minimum value for the number field of type 'double'.

multiple
Type : boolean
Default value : false

Flag to set the picklist to a multipicklist

overrideDefaultFormValidation
Type : boolean
Default value : false

Boolean when set to true overrides default form validaion. Defaulted to false.

picklistValues
Type : Array<ComplexArray>

Array of ComplexArray type as picklist values

placeholder
Type : string
Default value : ''

Placeholder string for the input.

presetBoolean
Type : boolean
Default value : false

Flag allows boolean dropdown values to be preset.

presetBooleanLabel
Type : string
Default value : ''

Preset label to be shown if presetBoolean is set to true.

readonly
Type : boolean
Default value : false

Flag to set this input as read only.

required
Type : boolean

Flag to set the input as required.

showLabel
Type : boolean
Default value : true

Boolean flag to show label for the input fields.

spinnerSize
Type : "large" | "small"
Default value : 'large'

Spinner size defines the size of spinner shown in the component. Possible values are small and large. Default spinner size is large.

textareaRows
Type : number
Default value : 3

The property specifies the visible height of a text area, in lines. By default value is 3.

valueClass
Type : boolean
Default value : false

To override the default styling of input field value, set the bootstrap classes of type string. Ex: 'mb-1'

<ng-container *ngIf="view$ | async as view">
  <div [ngSwitch]="view?.metadata?.DataType | lowercase" class="form-group align-items-center" [class.d-flex]="inline"
    [id]="uuid + '-container'">
    <label *ngIf="showLabel" [class.m-0]="inline" [class.mr-2]="inline" class="d-inline-block mutedLabels"
      [ngClass]="labelClass ? labelClass : 'font-weight-bold' ">{{(label) ? label :
      view?.metadata?.DisplayName}}</label>
    <i *ngIf="required && asterisk" class="fa fa-asterisk text-danger font-weight-normal custom-asterisk p-1"></i>

    <!-- Picklist -->
    <ng-container *ngSwitchCase="'picklist'">
      <ng-select class="form-control custom picklist p-0" [searchable]="false" [(ngModel)]="value" [required]="required" [class.form-control-sm]="inputSize == 'small'"
        [placeholder]="placeholder" [loading]="loading" [disabled]="readonly" (ngModelChange)="onPickChange(value)"
        #picklist="ngModel" [ngClass]="{ 'is-invalid': picklist.invalid && (picklist.touched || picklist.dirty), 'font-weight-bold': valueClass && value }"
        [items]="options" [multiple]="multiple" bindValue="value" bindLabel="label">
        <div class="invalid-feedback">{{errorMsg}}</div>
      </ng-select>

      <ng-template #checkboxes>
        <div *ngFor="let option of options$ | async" class="custom-control custom-radio" [class.custom-radio-sm]="inputSize == 'small'"
          [class.custom-control-inline]="inline">
          <input type="radio" class="custom-control-input" [name]="uuid + '_' + view?.metadata.FieldName"
            [value]="option.value" [id]="uuid + '_' + view?.metadata.FieldName + '_' + option.value" [(ngModel)]="value"
            (ngModelChange)="propagateChange(value)" [disabled]="readonly || option.disabled" [required]="required">
          <label class="custom-control-label mr-auto"
            [for]="uuid + '_' + view?.metadata.FieldName + '_' + option.value">
            {{option.label}}
          </label>
        </div>
      </ng-template>
    </ng-container>

    <!-- Boolean -->
    <ng-container *ngSwitchCase="'boolean'">
      <div *ngIf="displayFieldType === 'radio'; else booleanPicklist">
        <div class="form-check">
          <input type="radio" class="form-check-input" [id]="uuid + '_' + view?.metadata.FieldName + '_' + value"
            [name]="uuid + '_' + view?.metadata.FieldName" [checked]="value" (change)="onBooleanChange(true)">
          <label class="form-check-label" [for]="uuid + '_' + view?.metadata.FieldName + '_' + value">
            {{'COMMON.YES' | translate}}
          </label><br>
        </div>
        <div class="form-check">
          <input type="radio" class="form-check-input" [id]="uuid + '_' + view?.metadata.FieldName + '_' + !value"
            [name]="uuid + '_' + view?.metadata.FieldName" [checked]="!value" (change)="onBooleanChange(false)">
          <label class="form-check-label" [for]="uuid + '_' + view?.metadata.FieldName + '_' + !value">
            {{'COMMON.NO' | translate}}
          </label><br>
        </div>
      </div>

      <ng-template #booleanPicklist>
        <select type="radio" class="form-control" [class.form-control-sm]="inputSize == 'small'" *ngSwitchCase="'boolean'"
          [(ngModel)]="value" [class.custom-control-inline]="inline" (ngModelChange)="onBooleanChange(value)"
          [required]="required" [disabled]="readonly">
          <option *ngIf="presetBoolean" [value]="null"> {{presetBooleanLabel}} </option>
          <option [value]="true"> {{'COMMON.YES' | translate}} </option>
          <option [value]="false"> {{'COMMON.NO' | translate}} </option>
        </select>

      </ng-template>
    </ng-container>

    <!-- Multi select picklist -->
    <ng-container *ngSwitchCase="'multipicklist'">
      <div *ngIf="displayFieldType === 'dropdown'; else multiSelectCheckbox">
        <ng-select class="form-control custom picklist p-0" [searchable]="false" [(ngModel)]="value" [required]="required" [class.form-control-sm]="inputSize == 'small'"
          [placeholder]="placeholder" [loading]="loading" [disabled]="readonly" (ngModelChange)="onPickChange(value)"
          #picklist="ngModel" [ngClass]="{ 'is-invalid': picklist.invalid && (picklist.touched || picklist.dirty) }"
          [items]="options" [multiple]="true" bindValue="value" bindLabel="label">
          <div class="invalid-feedback">{{errorMsg}}</div>
        </ng-select>
      </div>
      <ng-template #multiSelectCheckbox>
        <div *ngFor="let option of options" class="custom-control custom-checkbox" [class.custom-checkbox-sm]="inputSize == 'small'"
          [class.custom-control-inline]="inline">
          <input type="checkbox" class="custom-control-input" [checked]="value && value?.indexOf(option.value) > -1"
            [id]="uuid + '_' + view?.metadata.FieldName + '_' + option.value" pattern="07[0-9]{9}"
            [(ngModel)]="getsetValue(option.value).value" (ngModelChange)="onMultiChange(option.value)"
            [disabled]="(enableValues?.length > 0 && enableValues?.indexOf(option.value) === -1) || readonly ? true : false"
            [required]="required">
          <label class="custom-control-label" [for]="uuid + '_' + view?.metadata.FieldName + '_' + option.value">
            {{option.label}}
          </label>
        </div>
      </ng-template>
    </ng-container>

    <!-- Number -->
    <ng-container *ngSwitchCase="'double'">
      <input type="number" [min]="minVal" class="form-control custom" [class.form-control-sm]="inputSize == 'small'" [id]="value"
        [(ngModel)]="value" [disabled]="readonly" (ngModelChange)="propagateChange(value)" [required]="required"
        [placeholder]="placeholder" #num="ngModel" step="any"
        [ngClass]="{ 'is-invalid': num.invalid && (num.touched || num.dirty) || value < minVal}" />
      <div class="invalid-feedback">{{errorMsg | translate}}</div>
    </ng-container>

    <ng-container *ngSwitchCase="'decimal'">
      <input type="number" [min]="minVal" class="form-control custom" [class.form-control-sm]="inputSize == 'small'" [id]="value"
        [(ngModel)]="value" [disabled]="readonly" (ngModelChange)="propagateChange(value)" [required]="required"
        [placeholder]="placeholder" #num="ngModel" step="any"
        [ngClass]="{ 'is-invalid': num.invalid && (num.touched || num.dirty) || value < minVal, 'font-weight-bold': valueClass }" />
      <div class="invalid-feedback">{{errorMsg | translate}}</div>
    </ng-container>

    <ng-container *ngSwitchCase="'int'">
      <input type="number" class="form-control custom" [class.form-control-sm]="inputSize == 'small'" [id]="value" [(ngModel)]="value"
        [disabled]="readonly" step="1" (ngModelChange)="propagateChange(value)" [required]="required"
        [placeholder]="placeholder" #num="ngModel"
        [ngClass]="{ 'is-invalid': num.invalid && (num.touched || num.dirty) }" />
      <div class="invalid-feedback">{{errorMsg | translate}}</div> 
    </ng-container>
    <!-- String -->
    <ng-container *ngSwitchCase="'string'">
      <ng-container *ngTemplateOutlet="stringTemplate"></ng-container>
    </ng-container>

    <!-- Long String -->
    <ng-container *ngSwitchCase="'longstring'">
      <ng-container *ngTemplateOutlet="stringTemplate"></ng-container>
    </ng-container>

    <ng-template #stringTemplate>
      <input type="text" class="form-control custom" [class.form-control-sm]="inputSize == 'small'" [id]="value" [(ngModel)]="value"
        (ngModelChange)="propagateChange(value)" [disabled]="readonly" [required]="required" [placeholder]="placeholder"
        #txt="ngModel"
        [ngClass]="{ 'is-invalid': overrideDefaultFormValidation || txt.invalid && (txt.touched || txt.dirty) }" />
      <div class="invalid-feedback">{{errorMsg | translate}}</div>
    </ng-template>

    <!-- Email -->
    <ng-container *ngSwitchCase="'email'">
      <input type="text" class="form-control custom" [class.form-control-sm]="inputSize == 'small'" [id]="value" [(ngModel)]="value"
        (ngModelChange)="propagateChange(value)" [required]="required" [placeholder]="placeholder" #email="ngModel"
        [ngClass]="{ 'is-invalid': email.invalid && (email.touched || email.dirty) }" />
      <div class="invalid-feedback">{{errorMsg}}</div>
    </ng-container>

    <!-- Textarea -->
    <ng-container *ngSwitchCase="'textarea'">
      <textarea [(ngModel)]="value" class="form-control custom" [class.form-control-sm]="inputSize == 'small'"
        (ngModelChange)="propagateChange(value)" [maxlength]="view?.metadata?.length" [rows]="textareaRows"
        [required]="required" [placeholder]="placeholder"></textarea>
    </ng-container>

    <!-- Date -->
    <div class="date-form position-relative" *ngSwitchCase="'date'">
      <input type="text" [id]="uuid" class="form-control custom" bsDatepicker [class.form-control-sm]="inputSize == 'small'"
        [value]="value" (bsValueChange)="onDateChange($event)" [required]="required" [placeholder]="placeholder"
        [bsConfig]="{ adaptivePosition: true }">
      <i class="fa fa-calendar"></i>
    </div>

    <!-- Datetime -->
    <div class="date-form position-relative" *ngSwitchCase="'datetime'">
      <input type="text" [id]="uuid" class="form-control custom" bsDatepicker [class.form-control-sm]="inputSize == 'small'"
        [value]="value" (bsValueChange)="onDatetimeChange($event)" [required]="required" [placeholder]="placeholder"
        [bsConfig]="{ adaptivePosition: true }">
      <i class="fa fa-calendar"></i>
    </div>

    <!-- Percentage -->
    <ng-container *ngSwitchCase="'percent'">
      <input type="text" [id]="uuid" class="form-control custom" [class.form-control-sm]="inputSize == 'small'"
        [ngModel]="value/100 | percent:'1.2'" (ngModelChange)="propagateChange(value)" [required]="required"
        [placeholder]="placeholder">
    </ng-container>

    <!-- Currency -->
    <ng-container *ngSwitchCase="'currency'">
      <input type="number" class="form-control custom" [class.form-control-sm]="inputSize == 'small'" [id]="value" [(ngModel)]="value"
        [disabled]="readonly" step=".01" (ngModelChange)="propagateChange(value)" [required]="required"
        [placeholder]="placeholder" #num="ngModel"
        [ngClass]="{ 'is-invalid': num.invalid && (num.touched || num.dirty) }" />
      <div class="invalid-feedback">{{errorMsg}}</div>
    </ng-container>

    <ng-container *ngSwitchCase="'reference'">
      <ng-container *ngTemplateOutlet="referenceTemplate"></ng-container>
    </ng-container>

    <ng-container *ngSwitchCase="'lookup'">
      <ng-container *ngTemplateOutlet="referenceTemplate"></ng-container>
    </ng-container>

    <!-- Reference template -->
    <ng-template #referenceTemplate>
      <ng-select class="form-control aptSingleSelectLookup p-0" [class.form-control-sm]="inputSize == 'small'"
        [class.contacts]="lookupOptions?.secondaryTextField" [(ngModel)]="lookupId" [items]="view?.lookupResults"
        (search)="onLookupSearch($event)" [required]="required" [bindLabel]="lookupOptions?.primaryTextField"
        bindValue="Id" [placeholder]="placeholder" [loading]="loading"
        (ngModelChange)="onLookupChange($event, view?.lookupResults)" #select="ngModel"
        [ngClass]="{ 'is-invalid': select.invalid && (select.touched || select.dirty) }" [disabled]="readonly"
        [clearable]="allowClearableLookups" (clear)="setLookupFieldData()" (focus)="setLookupFieldData()">
        <ng-template ng-option-tmp let-item="item" let-index="index" let-search="searchTerm">
          <span *ngIf="!lookupOptions?.secondaryTextField" class="basicOption" [ngOptionHighlight]="search">
            {{item[lookupOptions?.primaryTextField]}}
          </span>
          <div *ngIf="lookupOptions?.secondaryTextField" class="d-flex align-items-center contactOption">
            <img *ngIf="lookupOptions?.thumbnailField" class="rounded-circle mr-4" width="32" height="32"
              src="./assets/images/default.png" alt="Contact Image">
            <div class="d-flex flex-column h-100 justify-content-around">
              <span [ngOptionHighlight]="search">{{item[lookupOptions?.primaryTextField]}}</span>
              <i class="small" *ngIf="lookupOptions?.secondaryTextField">{{item[lookupOptions?.secondaryTextField]}}</i>
            </div>
          </div>
        </ng-template>
        <ng-template ng-loadingspinner-tmp>
          <apt-spinner [large]="spinnerSize === 'large'"></apt-spinner>
        </ng-template>
      </ng-select>
      <div class="invalid-feedback">{{errorMsg}}</div>
    </ng-template>

    <!-- Address -->
    <ng-container *ngSwitchCase="'address'">
      <apt-address [(ngModel)]="value"></apt-address>
    </ng-container>
  </div>
</ng-container>

./input-field.component.scss

apt-input-field {
  display: block;

  .custom-asterisk {
    font-size: 8px;
  }

  .form-control.is-invalid {
    padding-right: 0rem !important;
    background-size: 0%;
  }

  select {
    text-indent: 5px;
  }

  .date-form {

    input[bsdatepicker] {
      padding-right: 1.6rem;
    }

    i {
      position: absolute;
      top: 25%;
      right: 3%;
    }
  }

  .ng-select.picklist {
    .ng-select-container {
      height: 100%;
      min-height: 100%;
    }
  }

  .ng-select .ng-select-container {
    border: none
  }

  ng-select.aptSingleSelectLookup {

    &.ng-select-focused:not(.ng-select-opened):not(.ng-invalid)>.ng-select-container {
      border: 1.4px solid rgba(0, 36, 163, 1) !important;
      box-shadow: none !important;
    }

    .ng-select-container {
      background-color: transparent;
      min-height: 34px;
      height: 34px;
      border-width: 0px;

      .ng-arrow-wrapper {
        display: none;
      }

      apt-spinner {
        svg {
          width: 18px;
          height: 18px;
        }
      }

      .ng-clear-wrapper {
        padding-top: 0rem !important;
        padding-left: 0rem !important;  
        width: 24px;
        height: 24px;

        &:hover .ng-clear {
          opacity: 1;
        }

        .ng-clear {
          width: 24px;
          height: 24px;
          color: transparent;
          content: "";
          background-image: url("data:image/svg+xml,%3Csvg fill='%23000' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 24 24' class='ng-scope'%3E%3Cpolygon points='20 5.611 18.389 4 12 10.389 5.611 4 4 5.611 10.389 12 4 18.389 5.611 20 12 13.611 18.389 20 20 18.389 13.611 12'%3E%3C/polygon%3E%3C/svg%3E");
          opacity: 0.5;
        }
      }

      &::before {
        width: 24px;
        height: 24px;
        content: "";
        background-image: url("data:image/svg+xml,%3Csvg fill='%23000' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 24 24' class='ng-scope'%3E%3Cpath d='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'%3E%3C/path%3E%3C/svg%3E");
      }
    }

    &.ng-select-single .ng-select-container .ng-value-container .ng-input {
      padding-left: 34px;
      padding-right: 36px;

      &>input {
        cursor: text;
      }
    }

    &.contacts {
      .ng-dropdown-panel {
        bottom: auto !important;
      }
    }

    .ng-dropdown-panel {
      .ng-dropdown-header {
        font-size: 12px;
        padding-left: 14px;
        border: none;
      }

      .ng-dropdown-panel-items {
        .ng-option {
          min-height: 40px;
          padding: 4px 10px 4px 14px;

          .basicOption {
            line-height: 32px;
          }

          .contactOption {
            height: 56px;
          }
        }
      }
    }
  }

  .ng-select .ng-clear-wrapper {
    padding-top: 0.3125rem !important;
    padding-left: 0.3125rem !important;
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""