2.48.0 • Published 4 months ago

@memberjunction/ng-link-directives v2.48.0

Weekly downloads
-
License
ISC
Repository
-
Last release
4 months ago

@memberjunction/ng-link-directives

The @memberjunction/ng-link-directives package provides a set of Angular directives that transform text elements into different types of links based on MemberJunction entity field metadata. This makes it easy to display email addresses, URLs, and entity relationships as clickable links in your application.

Features

  • Email link directive (mjEmailLink) - Converts fields with "email" extended type to mailto: links
  • Web link directive (mjWebLink) - Converts fields with "url" extended type to external links
  • Field link directive (mjFieldLink) - Creates navigable links to related entity records
  • Automatic value resolution - Field links can display the related entity's name instead of ID
  • Smart navigation - Field links use Angular Router for seamless in-app navigation
  • Target control - Web and email links open in new tabs by default
  • CSS styling - All links use the link-text class for consistent styling
  • Type safety - Full TypeScript support with strict typing
  • Metadata integration - Leverages MemberJunction's metadata system for field information

Installation

npm install @memberjunction/ng-link-directives

Requirements

  • Angular 18.0.2 or higher
  • @memberjunction/core 2.43.0 or higher
  • TypeScript 4.0 or higher

Usage

Basic Setup

Import the LinkDirectivesModule in your Angular module:

import { NgModule } from '@angular/core';
import { LinkDirectivesModule } from '@memberjunction/ng-link-directives';

@NgModule({
  imports: [
    // other imports...
    LinkDirectivesModule
  ],
})
export class YourModule { }

Email Link Directive

The email link directive converts text into a mailto: link when the field has an extended type of "email".

<span [mjEmailLink]="field">{{ field.Value }}</span>
// In your component
import { EntityField } from '@memberjunction/core';

export class YourComponent {
  field: EntityField; // EntityField with ExtendedType = "email"
}

Note: The directive will log an error if the field's ExtendedType is not "email". There is a known issue where the error message incorrectly references "mjWebLink" instead of "mjEmailLink".

Web Link Directive

The web link directive converts text into an external URL link when the field has an extended type of "url".

<span [mjWebLink]="field">{{ field.Value }}</span>
// In your component
import { EntityField } from '@memberjunction/core';

export class YourComponent {
  field: EntityField; // EntityField with ExtendedType = "url"
}

Note: The directive will log an error if the field's ExtendedType is not "url". Links open in a new tab by default.

Field Link Directive

The field link directive creates a link to another entity record when the field is a foreign key to another entity.

<!-- Basic usage -->
<span [mjFieldLink]="true" [record]="customerRecord" [fieldName]="'AssignedUserID'">
  {{ customerRecord.Get('AssignedUserID') }}
</span>

<!-- With text replacement disabled -->
<span [mjFieldLink]="true" [record]="customerRecord" [fieldName]="'AssignedUserID'" [replaceText]="false">
  {{ customerRecord.Get('AssignedUserID') }}
</span>
// In your component
import { BaseEntity } from '@memberjunction/core';

export class YourComponent {
  customerRecord: BaseEntity; // Entity record containing the foreign key field
}

The directive:

  • Navigates to /resource/record/{primaryKey}?Entity={EntityName} when clicked
  • Automatically replaces the ID with the related entity's name (when replaceText=true)
  • Uses RelatedEntityNameFieldMap metadata for efficient name resolution
  • Falls back to server lookup if name mapping is not available

API Reference

EmailLink Directive

Selector: [mjEmailLink]

InputTypeRequiredDescription
fieldEntityFieldYesThe entity field object containing email data. Must have ExtendedType = "email"

WebLink Directive

Selector: [mjWebLink]

InputTypeRequiredDescription
fieldEntityFieldYesThe entity field object containing URL data. Must have ExtendedType = "url"

FieldLink Directive

Selector: [mjFieldLink]

InputTypeDefaultRequiredDescription
mjFieldLinkboolean-YesEnable the directive (must be set to true)
recordBaseEntity-YesThe entity record object containing the field
fieldNamestring-YesThe name of the field that contains the foreign key
replaceTextbooleantrueNoWhether to replace the field value with the related entity's name

Events: The directive handles click events internally to navigate using Angular Router.

Implementation Details

Base Link Class

All directives extend the BaseLink abstract class, which provides a common CreateLink method:

protected CreateLink(
  el: ElementRef, 
  field: EntityField, 
  renderer: Renderer2, 
  href: string, 
  newTab: boolean = false
): void

This method:

  • Creates an <a> element using Angular's Renderer2
  • Wraps the original element with the link
  • Adds the link-text CSS class
  • Sets target="_blank" for new tab behavior

Email Links

The EmailLink directive: 1. Validates that the field has ExtendedType = "email" 2. Prepends "mailto:" to the field value 3. Creates a link that opens the user's default email client 4. Always opens in a new tab

Web Links

The WebLink directive: 1. Validates that the field has ExtendedType = "url" 2. Uses the field value directly as the href 3. Creates an external link that opens in a new tab 4. Logs an error if the ExtendedType validation fails

Field Links

The FieldLink directive provides the most complex functionality:

  1. Metadata Resolution: Uses MemberJunction's metadata to find the related entity
  2. Navigation Setup: Constructs the route as /resource/record/{primaryKey}?Entity={EntityName}
  3. Name Resolution:
    • First checks RelatedEntityNameFieldMap for local field mapping
    • Falls back to GetEntityRecordName() API call if needed
  4. Click Handling: Intercepts clicks and uses Angular Router for navigation
  5. Error Handling: Includes navigation event monitoring for debugging

Note: Currently supports only single-value primary keys for foreign key relationships.

Styling

All generated links include the CSS class link-text for consistent styling across your application:

.link-text {
  color: #0066cc;
  text-decoration: underline;
  cursor: pointer;
}

.link-text:hover {
  color: #0052a3;
  text-decoration: none;
}

.link-text:visited {
  color: #551a8b;
}

Complete Example

Here's a complete example showing all three directives in action:

// component.ts
import { Component, OnInit } from '@angular/core';
import { BaseEntity, Metadata } from '@memberjunction/core';

@Component({
  selector: 'app-contact-details',
  template: `
    <div class="contact-info">
      <!-- Email link -->
      <div>
        Email: <span [mjEmailLink]="emailField">{{ contact.Get('Email') }}</span>
      </div>
      
      <!-- Web link -->
      <div>
        Website: <span [mjWebLink]="websiteField">{{ contact.Get('Website') }}</span>
      </div>
      
      <!-- Field link with name replacement -->
      <div>
        Account Manager: 
        <span [mjFieldLink]="true" [record]="contact" [fieldName]="'AccountManagerID'">
          {{ contact.Get('AccountManagerID') }}
        </span>
      </div>
    </div>
  `
})
export class ContactDetailsComponent implements OnInit {
  contact: BaseEntity;
  
  get emailField() {
    return this.contact.Fields.find(f => f.Name === 'Email');
  }
  
  get websiteField() {
    return this.contact.Fields.find(f => f.Name === 'Website');
  }
  
  async ngOnInit() {
    const md = new Metadata();
    this.contact = await md.GetEntityObject('Contacts');
    await this.contact.Load(123); // Load specific contact
  }
}

Build and Development

This package uses the Angular CLI compiler (ngc) for building:

# Build the package
npm run build

# The compiled output will be in the ./dist directory

The package is configured with:

  • TypeScript strict mode
  • ES2015 target with ES2020 modules
  • Source maps and declaration files
  • Angular compiler optimizations

Integration with MemberJunction

This package is designed to work seamlessly with the MemberJunction framework:

  • Metadata Integration: Leverages EntityField metadata for field type detection
  • Navigation: Integrates with MJ's standard routing patterns (/resource/record/...)
  • Entity System: Works with BaseEntity and EntityField objects
  • Name Resolution: Uses MJ's entity relationship mapping for efficient data display

Troubleshooting

Common Issues

  1. "Entity Field must have ExtendedType of URL" - Ensure your entity field metadata has the correct ExtendedType set
  2. Links not appearing - Verify the directive is properly applied and the field has a value
  3. Navigation errors - Check that the related entity exists in metadata and the route is configured

Debugging Tips

  • The FieldLink directive logs navigation events to the console
  • Use browser DevTools to inspect the generated link structure
  • Check that RelatedEntity metadata is properly configured for field links

License

ISC

Dependencies

  • Runtime Dependencies:

    • @memberjunction/core: ^2.43.0
    • tslib: ^2.3.0
  • Peer Dependencies:

    • @angular/common: ^18.0.2
    • @angular/core: ^18.0.2
    • @angular/router: ^18.0.2
  • Development Dependencies:

    • @angular/compiler: ^18.0.2
    • @angular/compiler-cli: ^18.0.2
2.23.2

8 months ago

2.46.0

5 months ago

2.23.1

8 months ago

2.34.0

6 months ago

2.19.4

9 months ago

2.19.5

9 months ago

2.19.2

9 months ago

2.19.3

9 months ago

2.19.0

9 months ago

2.19.1

9 months ago

2.34.2

6 months ago

2.34.1

6 months ago

2.45.0

5 months ago

2.22.1

9 months ago

2.22.0

9 months ago

2.22.2

9 months ago

2.33.0

6 months ago

2.18.3

9 months ago

2.18.1

9 months ago

2.18.2

9 months ago

2.18.0

9 months ago

2.21.0

9 months ago

2.44.0

5 months ago

2.29.0

8 months ago

2.29.2

7 months ago

2.29.1

8 months ago

2.32.0

7 months ago

2.32.2

7 months ago

2.32.1

7 months ago

2.17.0

9 months ago

2.43.0

5 months ago

2.20.2

9 months ago

2.20.3

9 months ago

2.20.0

9 months ago

2.20.1

9 months ago

2.28.0

8 months ago

2.31.0

7 months ago

2.39.0

5 months ago

2.16.1

9 months ago

2.16.0

9 months ago

2.42.1

5 months ago

2.42.0

5 months ago

2.27.1

8 months ago

2.27.0

8 months ago

2.30.0

7 months ago

2.15.2

9 months ago

2.15.1

9 months ago

2.38.0

5 months ago

2.41.0

5 months ago

2.26.1

8 months ago

2.26.0

8 months ago

2.37.1

5 months ago

2.37.0

6 months ago

2.14.0

10 months ago

2.40.0

5 months ago

2.25.0

8 months ago

2.48.0

4 months ago

2.13.4

10 months ago

2.36.0

6 months ago

2.13.2

11 months ago

2.13.3

10 months ago

2.13.0

11 months ago

2.36.1

6 months ago

2.13.1

11 months ago

2.47.0

4 months ago

2.24.1

8 months ago

2.24.0

8 months ago

2.12.0

12 months ago

2.35.1

6 months ago

2.35.0

6 months ago

2.23.0

8 months ago

2.11.0

12 months ago

2.10.0

12 months ago

2.9.0

12 months ago

2.8.0

1 year ago

2.7.0

1 year ago

2.7.1

1 year ago

2.6.1

1 year ago

2.6.0

1 year ago

2.5.2

1 year ago

1.6.1

1 year ago

1.6.0

1 year ago

2.4.1

1 year ago

2.4.0

1 year ago

2.0.0

1 year ago

1.5.3

1 year ago

1.5.2

1 year ago

1.5.1

1 year ago

1.5.0

1 year ago

2.3.0

1 year ago

2.3.2

1 year ago

2.3.1

1 year ago

2.3.3

1 year ago

1.8.1

1 year ago

1.8.0

1 year ago

1.4.1

1 year ago

1.4.0

1 year ago

2.2.1

1 year ago

2.2.0

1 year ago

1.7.1

1 year ago

1.7.0

1 year ago

1.3.3

1 year ago

1.3.2

1 year ago

1.3.1

1 year ago

1.3.0

1 year ago

2.1.2

1 year ago

2.1.1

1 year ago

2.5.0

1 year ago

2.1.4

1 year ago

2.1.3

1 year ago

2.5.1

1 year ago

2.1.5

1 year ago

2.1.0

1 year ago

1.2.2

1 year ago

1.2.1

1 year ago

1.2.0

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.1.3

1 year ago

1.1.2

1 year ago

1.0.11

1 year ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.8-next.6

2 years ago

1.0.8-next.5

2 years ago

1.0.8-next.4

2 years ago

1.0.8-next.3

2 years ago

1.0.8-next.2

2 years ago

1.0.8-next.1

2 years ago

1.0.8-next.0

2 years ago

1.0.7-next.0

2 years ago

1.0.8-beta.0

2 years ago

1.0.6

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.9.143

2 years ago

0.9.142

2 years ago

0.9.141

2 years ago

0.9.140

2 years ago

0.9.139

2 years ago

0.9.138

2 years ago

0.9.134

2 years ago

0.9.136

2 years ago

0.9.135

2 years ago

0.9.137

2 years ago

0.9.133

2 years ago

0.9.131

2 years ago

0.9.130

2 years ago

0.9.132

2 years ago

0.9.128

2 years ago

0.9.127

2 years ago

0.9.125

2 years ago

0.9.124

2 years ago

0.9.123

2 years ago

0.9.121

2 years ago

0.9.120

2 years ago

0.9.122

2 years ago

0.9.118

2 years ago

0.9.119

2 years ago

0.9.116

2 years ago

0.9.115

2 years ago

0.9.114

2 years ago

0.9.110

2 years ago

0.9.112

2 years ago

0.9.111

2 years ago

0.9.109

2 years ago

0.9.113

2 years ago

0.9.108

2 years ago

0.9.107

2 years ago

0.9.106

2 years ago

0.9.105

2 years ago

0.9.104

2 years ago

0.9.103

2 years ago

0.9.97

2 years ago

0.9.91

2 years ago

0.9.85

2 years ago

0.9.86

2 years ago

0.9.84

2 years ago

0.9.81

2 years ago

0.9.82

2 years ago

0.9.83

2 years ago

0.9.80

2 years ago

0.9.78

2 years ago

0.9.79

2 years ago

0.9.74

2 years ago

0.9.75

2 years ago

0.9.76

2 years ago

0.9.77

2 years ago

0.9.73

2 years ago

0.9.67

2 years ago

0.9.68

2 years ago

0.9.63

2 years ago

0.9.64

2 years ago

0.9.65

2 years ago

0.9.66

2 years ago

0.9.60

2 years ago

0.9.61

2 years ago

0.9.62

2 years ago

0.9.59

2 years ago

0.9.57

2 years ago

0.9.58

2 years ago

0.9.56

2 years ago

0.9.52

2 years ago

0.9.53

2 years ago

0.9.54

2 years ago

0.9.55

2 years ago

0.9.51

2 years ago

0.9.50

2 years ago

0.9.48

2 years ago

0.9.49

2 years ago

0.9.46

2 years ago

0.9.47

2 years ago

0.9.45

2 years ago

0.9.44

2 years ago

0.9.43

2 years ago

0.9.42

2 years ago

0.9.41

2 years ago

0.9.40

2 years ago

0.9.39

2 years ago

0.9.38

2 years ago

0.9.37

2 years ago

0.9.36

2 years ago

0.9.35

2 years ago

0.9.34

2 years ago

0.9.33

2 years ago

0.9.32

2 years ago

0.9.30

2 years ago

0.9.29

2 years ago

0.9.28

2 years ago

0.9.27

2 years ago

0.9.26

2 years ago

0.9.25

2 years ago

0.9.24

2 years ago

0.9.23

2 years ago

0.9.22

2 years ago

0.9.21

2 years ago

0.9.20

2 years ago

0.9.19

2 years ago

0.9.18

2 years ago

0.9.17

2 years ago

0.9.16

2 years ago

0.9.15

2 years ago

0.9.14

2 years ago

0.9.13

2 years ago

0.9.12

2 years ago

0.9.11

2 years ago

0.9.10

2 years ago

0.9.9

2 years ago

0.9.8

2 years ago

0.9.7

2 years ago

0.9.6

2 years ago

0.9.5

2 years ago

0.9.4

2 years ago

0.9.3

2 years ago

0.9.2

2 years ago

0.9.1

2 years ago