npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@eqproject/eqp-lookup

v3.0.0

Published

Dynamic lookup - Angular Material based

Downloads

31

Readme

Table of contents

Required

  • [x] Angular Material installed and imported
  • [x] ng-select installed and imported (v. 10.0.4)

Getting started

Step 1: Install eqp-lookup:

NPM


npm install  --save  @eqproject/eqp-lookup

Step 2: Import the EqpLookupModule:


import { EqpLookupModule } from  '@eqproject/eqp-lookup';

  

@NgModule({
    declarations: [AppComponent],
    imports: [EqpLookupModule],
    bootstrap: [AppComponent]
})

export class AppModule {}

Step 3: Import ng-select styling:

Style.scss


@import  "~@ng-select/ng-select/themes/material.theme.css";

API

Inputs

| Input | Type | Default | Required | Description | | ------------- | ------------- | ------------- | ------------- | ------------- | | [placeholder] | string | - | no | Text displayed as placeholder when no item is selected. | | [bindLabel] | string | 'Label' | no | Object property to use for label. | | [bindKey] | string | 'ID' | no | Object property to use for key. | | [items] | Array<objects> | - | no | Array of objects that lookup will show. | | [notFoundText] | string | 'Nessun risultato trovato' | no | Custom text when filter returns empty result. | | [genericAddComponent] | DynamicLoaderDirectiveData | - | no | Object containing the templateRef, inputParams and other configuration parameters to add elements into the datasource. | | [isMultiple] | boolean | false | no | Defines if the lookup can accept more values, managed like an object array. | | [isSearchable] | boolean | true | no | Defines if it's possible to type inside lookup and search among items. | | [isClearable] | boolean | true | no | Defines if the cancel button is shown. | | [isVirtualScroll] | boolean | false | no | Dynamic render of the items contained in the lookup. Useful in case of huge amount of data. | | [isReadonly] | boolean | false | no | Set lookup as readonly. | | [isRequired] | boolean | false | no | Set lookup as required. | | [isDisabled] | boolean | false | no | Disable the lookup. | | [entityType] | string | - | yes | Entity name to be searched on the server when the mode chosen isn't the one with initialItems. | | [formGroupInput] | any | - | no | FormGroup that contains the specific FormControl of the lookup (to use if you're not using ngModelInput). | | [formControlNameInput] | any | - | no | FormControl to use inside the FormGroup passed (to use if you're not using ngModelInput). | | [ngModelInput] | any | - | no | ngModel binded to lookup. (to use if you're not using FormControl) | | [isSearchWhileComposing] | boolean | false | no | Whether items should be filtered while composition started. | | [bindCompleteObject] | boolean | true | no | Whether the binded object must be ID or the full object. | | [appendToInput] | string | - | no | Input used when the lookup is contained inside a dialog or tab and there are visualization problems. Useful value: body. | | [disableReloadOnLookupAddingCompleteParent] | boolean | false | no | Whether data must be reloaded after adding is complete. | | [showOptionTooltip] | boolean | false | no | Defines if a tooltip must be shown on option hover. | | [sortList] | boolean | false | no | Items sorting based on Label. | | [dataFilter] | Array<LinqPredicateDTO> | - | no | It allows you to pass some simple filters to the server (used when fullUrlHttpCall is also passed) | | [customConfig] | LookupCustomConfig | - | no | Configuration related to properties that compose the label and to full object inclusion (used when fullUrlHttpCall is also passed). | | [complexDataFilter] | Array<ComplexLinqPredicateDTO> | - | no | It allows you to pass some complex filters to the server (used when fullUrlHttpCall is also passed) | | [initialItems] | Array<any> | false | no | Initial datasource used if you want to bypass the server call. | | [ngModelOptions] | any | - | no | Options related to ngModel. | | [isEditable] | boolean | false | no | Defines if the selected item can be edited. | | [isMultiline] | boolean | false | no | Defines if the item selected's label can be shown inside a multiple line input. | | [dropdownPosition] | auto \| top \| bottom | auto | no | Specifies the position of the dropdown. | | [selectOnTab] | boolean | false | no | Select marked dropdown item using tab. | | [fullUrlHttpCall] | string | - | no | Full HTTP url for the server call. | | [addButtonText] | string | false | no | Text displayed as tooltip when hovering on the add button. | | [editButtonText] | string | false | no | Text displayed as tooltip when hovering on the edit button. | | [selectAll] | boolean | false | no | Add an option inside the dropdown that allows the user to select all the elements. | | [selectAllText] | string | 'Seleziona tutto' | no | Text displayed in the select all option. | | [groupBy] | string \| Function | - | no | Allow to group items by key or function expression. | | [groupValue] | (groupKey: string, children: any[]) => Object | - | no | Function expression to provide group value. | | [groupByProperty] | string | - | no | Property name used to group items. | | [selectableGroup] | boolean | false | no | Allow to select group when groupBy is used. | | [selectableGroupAsModel] | boolean | false | no | Indicates whether to select all children or group itself. | | [clearAllText] | string | - | no | Text displayed as tooltip when hovering the clear button. | | [customOption] | TemplateRef | - | no | Custom template for the option inside the dropdown panel. | | [customLabel] | TemplateRef | - | no | Custom template for the selected item's label. | | [manipulateDataFn] | (items: any) => LookupDTO[] | - | no | Function to manipulate data after the HTTP call used to retrieve items. | | [compareFunction] | (iteratedObject: any, bindedObject: any) => boolean | - | no | Function to compare the option values with the selected values. A boolean should be returned. |

Outputs

| Output| Event arguments | Required | Description | | ------------- | ------------- | ------------- | ------------- | | (ngModelInputChange) | any | - | Invoked when the value changes and the ngModelInput is binded. When items are grouped it return the group 'exploded'. | | (formControlChange) | any | - | Invoked when the value changes and a form control is binded. When items are grouped it return the group 'exploded'. | | (lookupAddingCompleteParent) | any | - | Event emitted when the add process is completed and disableReloadOnLookupAddingCompleteParent is not true. | | (searchChange) | any | - | Invoked when user searches among lookup items. It return the term typed and items filtered. | | (keydown) | any | - | Invoked on keydown. | | (clear) | any | - | Event emitted on select clear. | | (valueSelected) | any | - | Event emitted when a value is selected. |

Use cases

Case 1: Lookup with initial items :

<eqp-lookup
	placeholder="Lookup with initial items"
	[entityType]="'Question'"
	[initialItems]="questionInitialItems"
	[formGroupInput]="lookupFormGroup"
	[formControlNameInput]="'lookupWithInitialItems'"
	(formControlChange)="lookupChange($event)"
></eqp-lookup>

Define properties and functions in Typescript (or Javascript) file

lookupFormGroup : FormGroup | undefined;

...

createForm() {
	this.lookupFormGroup = this.formBuilder.group({
		lookupWithInitialItems: [null, Validators.required],
	})
}

...

this.http.post<LookupDTO[]>(url, config).subscribe(res  => {
	this.questionInitialItems = res;
})

...

lookupChange(event: any) {
	// body
}

Case 2: Lookup with HTTP call and ngModelInput :

Define component selector in HTML

<eqp-lookup
	placeholder="Lookup with HTTP call"
	[entityType]="'Question'"
	[fullUrlHttpCall]="fullUrlHttpCall"
	[(ngModelInput)]="lookupWithHttpCall"
	(ngModelInputChange)="lookupChange($event)"
	[isMultiline]="true"
></eqp-lookup>

Define properties and functions in Typescript (or Javascript) file

fullUrlHttpCall = environment.apiFullUrl + '/lookup/GetLookupEntities';
lookupWithHttpCall: LookupDTO | undefined;

...

lookupChange(event: any) {
	// body
}

Case 3: Lookup with HTTP call and Form :

Define component selector in HTML

<eqp-lookup
	placeholder="Lookup with aform"
	[entityType]="'Question'"
	[fullUrlHttpCall]="fullUrlHttpCall"
	[formGroupInput]="lookupFormGroup"
	[formControlNameInput]="'lookupWithForm'"
	(formControlChange)="lookupChange($event)"
	[isMultiline]="true"
></eqp-lookup>

Define properties and functions in Typescript (or Javascript) file

fullUrlHttpCall = environment.apiFullUrl + '/lookup/GetLookupEntities';
lookupFormGroup : FormGroup | undefined;
...

createForm() {
	this.lookupFormGroup = this.formBuilder.group({
		lookupWithForm: [null, Validators.required],
	})
}

...

lookupChange(event: any) {
	// body
}

Case 4: Lookup with HTTP call and extra configs :

Define component selector in HTML

<eqp-lookup
	[entityType]="'City'"
	placeholder="Città"
	[fullUrlHttpCall]="fullUrlHttpCall"
	[formGroupInput]="lookupFormGroup"
	[formControlNameInput]="'lookupWithExtraConfigs'"
	(formControlChange)="lookupChange($event)"
	[dataFilter]="[{PropertyFilters: [{PropertyName: 'FK_Province', PropertyValue: 10, RelationType: 1}]}]"
	[customConfig]="{LabelProperties: ['Name', 'Code', 'ID'], IncludeFullObject: true}"
></eqp-lookup>

Define properties and functions in Typescript (or Javascript) file

fullUrlHttpCall = environment.apiFullUrl + '/lookup/GetLookupEntities';
lookupFormGroup : FormGroup | undefined;

...

createForm() {
	this.lookupFormGroup = this.formBuilder.group({
		lookupWithExtraConfigs: [null, Validators.required],
	})
}

...

lookupChange(event: any) {
	// body
}

Case 5: Editable Lookup :

Define component selector in HTML

<eqp-lookup
	placeholder="Editable lookup"
	[entityType]="'Question'"
	[fullUrlHttpCall]="fullUrlHttpCall"
	[genericAddComponent]="{componentSelector: addQuestionComponent, idLookupEntity: getNumber(getFormControls('editableLookup').value), isEditable: true, disableRedirectAfterSave: true}"
	[isVirtualScroll]="true"
	[formGroupInput]="lookupFormGroup"
	[formControlNameInput]="'editableLookup'"
	(formControlChange)="lookupChange($event)"
	[isMultiline]="true"
	[isEditable]="true"
></eqp-lookup>

Define properties and functions in Typescript (or Javascript) file

fullUrlHttpCall = environment.apiFullUrl + '/lookup/GetLookupEntities';
lookupFormGroup : FormGroup | undefined;
addQuestionComponent = AddQuestionComponent;
...

createForm() {
	this.lookupFormGroup = this.formBuilder.group({
		editableLookup: [null, Validators.required],
	})
}

...

getNumber(element: number | string | undefined | null): number | null {
	if (element != null)
		return  Number(element);
	else
		return  <null><unknown>  element;
}

...

getFormControls(control: string) {
	return  this.lookupFormGroup.controls[control];
}

...

lookupChange(event: any) {
	// body
}

Case 6: Lookup with select all :

Define component selector in HTML

<eqp-lookup
	placeholder="Lookup with select all"
	[entityType]="'Question'"
	[fullUrlHttpCall]="fullUrlHttpCall"
	[isVirtualScroll]="true"
	(formControlChange)="lookupChange($event)"
	[formGroupInput]="lookupFormGroup"
	[formControlNameInput]="'lookupWithSelectAll'"
	[isMultiline]="true"
	[isEditable]="true"
	[selectAll]="true"
	[isMultiple]="true"
	[selectableGroupAsModel]="true"
></eqp-lookup>

Define properties and functions in Typescript (or Javascript) file

fullUrlHttpCall = environment.apiFullUrl + '/lookup/GetLookupEntities';
lookupFormGroup : FormGroup | undefined;
...

createForm() {
	this.lookupFormGroup = this.formBuilder.group({
		lookupWithSelectAll: [null, Validators.required],
	})
}

...

lookupChange(event: any) {
	// body
}

Case 7: Lookup with groups :

Define component selector in HTML

<eqp-lookup
	placeholder="Lookup with groups"
	[entityType]="'Question'"
	[fullUrlHttpCall]="fullUrlHttpCall"
	[isVirtualScroll]="true"
	[formGroupInput]="lookupFormGroup"
	[formControlNameInput]="'lookupWithGroups'"
	(formControlChange)="lookupChange($event)"
	[isMultiline]="true"
	[groupBy]="groupByFn"
	[groupValue]="groupValueFn"
	[groupByProperty]="'FullObject.FK_QuestionCategory'"
	[isMultiple]="true"
	[selectableGroup]="true"
	[selectableGroupAsModel]="true"
></eqp-lookup>

Define properties and functions in Typescript (or Javascript) file

fullUrlHttpCall = environment.apiFullUrl + '/lookup/GetLookupEntities';
lookupFormGroup : FormGroup | undefined;
groupByFn = (item: any) =>  item.FullObject.FK_QuestionCategory
groupValueFn = (groupKey: string, children: any[]) => ({Key:  groupKey, Label:  groupKey, Total:  children.length});
...

createForm() {
	this.lookupFormGroup = this.formBuilder.group({
		lookupWithGroups: [null, Validators.required],
	})
}

...

lookupChange(event: any) {
	// body
}

NB: It's possible to change the Label displayed for groups passing some values or using the groupKey to access the selected properties inside an array.

Case 8: Lookup with data manipulation and custom templates :

Define component selector in HTML

<eqp-lookup
	placeholder="Lookup with function and custom templates"
	[entityType]="'Question'"
	[fullUrlHttpCall]="fullUrlHttpCall"
	[formGroupInput]="lookupFormGroup"
	[formControlNameInput]="'lookupWithFunctionAndCustomTemplates'"
	(formControlChange)="lookupChange($event)"
	[isMultiline]="true"
	[selectAll]="true"
	[customOption]="customOptionTemplate"
	[customLabel]="customLabelTemplate"
	[manipulateDataFn]="manipulateData"
></eqp-lookup>

Define custom templates in HTML

<!-- Template for option inside the dropdown panel -->
<ng-template  #customOptionTemplate  ng-option-tmp  let-item="item"  let-index="index"  let-search="searchTerm">
	<div class="card">
		<div  class="card-body">
			<h5  class="card-title">{{item.Label}}</h5>
			<h6  class="card-subtitle mb-2 text-muted">Card subtitle</h6>
			<p  class="card-text">
				Some quick example text to build
			</p>
			<div>
				<a  href="#"  class="card-link">Card link</a>
				<a  href="#"  class="card-link">Another link</a>
			</div>
		</div>
	</div>
</ng-template>

<!-- Selected items' Label template -->
<ng-template  #customLabelTemplate  ng-label-tmp  let-item="item"  let-clear="clear">
	<span  title="{{item.Label}}">Custom template:  {{item.Label}}</span>
	<span  *ngIf="item.Total"  class="ml-1 badge badge-secondary"  style="color: black !important">{{item.Total}}</span>
	<span  class="ng-value-icon right"  (click)="clear(item)"  aria-hidden="true"> x </span>
</ng-template>

Define properties and functions in Typescript (or Javascript) file

fullUrlHttpCall = environment.apiFullUrl + '/lookup/GetLookupEntities';
lookupFormGroup : FormGroup | undefined;
@ViewChild("customOptionTemplate") customOptionTemplate: TemplateRef<any>;
@ViewChild("customLabelTemplate") customLabelTemplate: TemplateRef<any>;
...

createForm() {
	this.lookupFormGroup = this.formBuilder.group({
		lookupWithFunctionAndCustomTemplates: [null, Validators.required],
	})
}

manipulateData(items: any) : LookupDTO[] {
	let  res: LookupDTO[] = [];
	for(let  item  of  items) {
		item.Label += " added later";
		res.push(item)
	}
	return  res;
}

...

lookupChange(event: any) {
	// body
}

Credits

This library has been developed by EqProject SRL, for more info contact: [email protected]