@jaspero/ng-helpers
A collection of useful components, directives and pipes for Angular applications.Every item (component, directive and pipe) is published in a separate module, making it easy to just import modules your application will use and not increase bundle size unnecessarily.
- ClickOutsideDirective - FormTouchOnHoverDirective - StopPropagationDirective - DebounceChangeDirective - TrackByField - LoadClickDirective - EnumPipe - SanitizePipe - TimePassedPipe - EnumKeyFormatPipe - OnChange
Installation
To install this library, run:$ npm install --save @jaspero/ng-helpers
Then import any Module you need. For example if you need the
ClickOutsideDirective
import the ClickOutsideModule
.Components
Directives
ClickOutsideDirective
This directive listens for emitted events on the window object and emits if the event doesn't contain the target element.Example
<div (jpClickOutside)="doSomething()"></div>
Use Cases
- Closing modals, dropdowns, mobile navigations when clicked outside.
- Toggling off one item when another is clicked (accordion)
Outputs
| name | description | | -------------- | ------------------------------------------------------- | | jpClickOutside | Emits when current element isn't contained in the event |Inputs
| name | type | default | description | | --------------------- | ------- | ------- | ------------------------------------- | | clickOutsideEventType | string | 'click' | event to listen for | | clickOutsideBlock | boolean | false | if truejpClickOutside
doesn't emit |FormTouchOnHoverDirective
This directive requires aFormGroup
or FormArray
then on mouseenter loops over all controls and marks them touched.Example
<form [formGroup]="someForm">
<input type="text" formControlName="someControl">
<!--We wrapp the button so that we get mouseover event's even when the submit is disabled-->
<div jpFormTouchOnHover>
<button type="submit" [disabled]="someForm.invalid">Save</button>
</div>
</form>
Use Cases
- This directive is particularly useful when you want to provide information on why the submit button is disabled.
Outputs
| name | description | | ------------------ | ---------------------------------------------------------------- | | jpFormTouchOnHover | Emits when controls finish looping and every element was touched |Inputs
| name | type | default | description | | ------------- | ---------------------- | ------- | ---------------------------- | | jpFormTouched | FormGroup or FormArray | null | set of controls to loop over |StopPropagationDirective
Listens for the emitted event on the target element and simply forwards it along and callsevent.stopPropagation()
.Example
<button (jpStopPropagation)="doSomething()">Click</button>
Use Cases
- When ever you need to stopPropagation on an event, you can use this directive rather then passing the event along
Outputs
| name | description | | ----------------- | ------------------------------------------------------ | | jpStopPropagation | Emits the original event after calling stopPropagation |Inputs
| name | type | default | description | | ------------------------ | ------- | ------- | ------------------------------------------------ | | preventDefault | boolean | false | shouldevent.preventDefault()
also get called. |
| stopPropagationEventType | string | 'click' | what event to listen for |
| condition | boolean or (event) => boolean | undefined | a condition to check before calling event.stopPropagation()
|DebounceChangeDirective
Listens for the emitted event on the target element and simply forwards it along afterdebounceTime
.Example
<input type="text" (jpDebounceChange)="doSomething()" />
Use Cases
- When ever you need to emit events with a delay
Outputs
| name | description | | ---------------- | --------------------------------------- | | jpDebounceChange | emits original event after debounceTime |Inputs
| name | type | default | description | | ----------------------- | ------- | ------- | ---------------------------------------- | | debounceTime | number | 500 | value to pass to thedebounceTime
pipe |
| debounceChangeEventType | string | 'keyup' | what event to listen for |
| emitOnlyOnChange | boolean | false | only emit event if the value changes |TrackByFieldDirective
Example
<div *ngFor="let item of items; jpTrackByField:'test'"></div>
@NgModule({
imports: [TrackByFieldModule.defaultKey()]
})
export class Module {}
LoadClickDirective
Listens for the emitted click event on the target element and add loading class.Example
<button [jpLoadClick]="save()">Submit</button>
Use Cases
- For preventing double click on the submit button.
Inputs
| name | type | default | description | | ------------------------ | --------------- | --------- | ---------------------------------------- | | jpLoadClick | Observable | null || loadClickClass | string | 'loading' |
| loadClickStopPropagation | boolean | false | Should
stopPropagation
be called.
| loadClickEventType | string | 'click' |
| loadClickPreventDefault | boolean | false | Should preventDefault
be called.
| disableAttribute | boolean | true | Should the disabled attribute be attached to the element. Pipes
EnumPipe
A very simple pipe that returns an array of{key: number, value: string}
objects from an enum.Example
<select>
<option *ngFor="let item of someEnum | jpEnum" [value]="item.key">
{{item.value}}
</option>
</select>
Use Cases
- It's most commonly used to easily iterate over an enum in a select
Input Value
| value | type | description | | ----- | ---- | ------------------------------------------------------------------------------------------------ | | value | enum | Supports any enum value. Provide it in typescriptsomeEnum = SomeEnum
to iterate over in html. |Parameters
No parameters forEnumPipe
SanitizePipe
Simplifies using ofDomSanitizer
. The pipe accepts any value and then tries to sanitize it to the desired format.Example
<div [innerHtml]="unsanitizedHtml | jpSanitize:'html'"></div>
Use Cases
- Rendering raw html, styles...
Input Value
| value | type | description | | ----- | ------ | ----------------------------------------------------------------- | | value | string | Accepts any unsanitized string and runs it throughDomSanitizer
|Parameters
| param | type | default | description | | ----- | --------------------------------------------- | ------- | -------------------------------------------------------------------------- | | type | html or style or script or url or resourceUrl | html | Type of entry value. This determines whatDomSanitizer
method get's used |TimePassedPipe
This pipe takes a date as input and returns the elapsed time since that date as a number in the desired format.Example
<div>
{{someDate | jpTimePassed:null:timePassedType.Minute}} minutes ago
</div>
Use Cases
- Displaying elapsed time
Input Value
| value | type | description | | ----- | ---- | ----------- | | value | Date | any date |Parameters
| param | type | default | description | | ------- | -------------- | --------------------- | ------------------------------------------------------------------------- | | dateTwo | Date | current date | This is the ending date in the interval. It defaults to the current date. | | type | TimePassedType | TimePassedType.Minute | In what time format should the elapsed time be returned in. |EnumKeyFormatPipe
Example
<div *ngFor="let item of someObject | jpArrayFromObject">
<span>KEY: {{item.key}}</span>
<span>VALUE: {{item.value}}</span>
</div>
Use Cases
- This pipe is useful when ever you need to iterate an object in your template
Input Value
| value | type | description | | ----- | ------ | ----------- | | value | object | any object |Parameters
No parameters forArrayFromObjectPipe
Decorators
OnChange
A decorator for change detection on propertiesExample
export class AppComponent {
@OnChange<string>((value, simpleChange) => {
console.log(`Title is changed to: ${value}`);
})
@Input()
title: string;
}
JpFunction
Decorator for methods used by LoadClickDirective.Wraps them in function and expects return of type Observable.
Parameters
| value | type | description | | ----- | ------ | ----------- | | take | number | When JpFunction is called programmatically by default append take(1) to Observable. Pass 0 to skip take operator. |Example
@JpFunction()
waitFor(milliseconds: number = 1000) {
return of(true).pipe(
delay(milliseconds)
);
}
@JpFunction({take: 2})
count() {
return interval(10).pipe(
tap((index) => {
console.log(index);
})
);
}
ngOnInit() {
// Triggers console.log for 0 and 1
this.count();
}