@memberjunction/ng-core-entity-forms v2.48.0
@memberjunction/ng-core-entity-forms
The @memberjunction/ng-core-entity-forms
package provides a comprehensive set of Angular form components for all core MemberJunction entities. It includes both auto-generated form components based on entity metadata and custom form components with enhanced functionality for specific entities.
Features
- Pre-built form components for all MemberJunction core entities
- Automatically generated forms with consistent UI across the platform
- Custom form implementations for complex entities
- Support for detail sections, tabs, and specialized form layouts
- Integration with MemberJunction's metadata system
- Tree-shake safe implementation for production builds
- Form components following MemberJunction's design patterns
Installation
npm install @memberjunction/ng-core-entity-forms
Requirements
- Angular 18+
- @memberjunction/core
- @memberjunction/core-entities
- @memberjunction/ng-explorer-core
- @memberjunction/ng-base-forms
- Various MemberJunction and Kendo UI components
Usage
The package includes two main modules:
CoreGeneratedFormsModule
- Contains all auto-generated form componentsMemberJunctionCoreEntityFormsModule
- Contains custom form components
Basic Setup
Import the necessary modules in your application module:
import {
CoreGeneratedFormsModule,
MemberJunctionCoreEntityFormsModule
} from '@memberjunction/ng-core-entity-forms';
@NgModule({
imports: [
// other imports...
CoreGeneratedFormsModule,
MemberJunctionCoreEntityFormsModule
],
})
export class YourModule { }
Using Generated Forms
Generated forms are dynamically loaded based on entity names. The typical pattern is to use a component factory to create the appropriate form component:
import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { Metadata } from '@memberjunction/core';
@Component({
selector: 'app-entity-form-container',
template: '<ng-container #formContainer></ng-container>'
})
export class EntityFormContainerComponent {
@ViewChild('formContainer', { read: ViewContainerRef }) formContainer!: ViewContainerRef;
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private metadata: Metadata
) {}
async loadEntityForm(entityName: string, recordId: any) {
// Clear the container
this.formContainer.clear();
// Get the form component class for the entity
const formComponent = await this.metadata.GetEntityFormComponent(entityName);
if (formComponent) {
// Create the component
const factory = this.componentFactoryResolver.resolveComponentFactory(formComponent);
const componentRef = this.formContainer.createComponent(factory);
// Set inputs
componentRef.instance.recordId = recordId;
// Initialize the form
await componentRef.instance.ngOnInit();
}
}
}
Using Custom Forms
Custom forms can be used directly in your templates:
<!-- For the extended Entity form -->
<mj-entities-form
[recordId]="entityId"
[showToolbar]="true"
(saved)="onEntitySaved($event)">
</mj-entities-form>
<!-- For the extended EntityAction form -->
<mj-entity-action-form
[recordId]="actionId"
[showToolbar]="true"
(saved)="onActionSaved($event)">
</mj-entity-action-form>
Architecture
Generated Forms
The CoreGeneratedFormsModule
contains multiple sub-modules that collectively register all generated form components. Each entity has:
- A main form component (e.g.,
EntityFormComponent
) - Multiple section components (e.g.,
EntityDetailsComponent
,EntityTopComponent
) - A loader function to prevent tree-shaking (e.g.,
LoadEntityFormComponent()
)
Custom Forms
The MemberJunctionCoreEntityFormsModule
contains extended form components that provide additional functionality beyond the auto-generated forms:
EntityFormExtendedComponent
- Enhanced form for Entity managementEntityActionExtendedFormComponent
- Enhanced form for EntityAction managementActionTopComponentExtended
- Custom top section for Action forms
Custom Form Development Guide
Core Architecture & Setup
- Location: Custom forms live in
packages/Angular/Explorer/core-entity-forms/src/lib/custom/{EntityName}/
- File Structure:
{entity-name}-form.component.ts
(main logic){entity-name}-form.component.html
(template)
- Inheritance: Extend generated form components (e.g.,
TemplateFormComponent
) which inherit fromBaseFormComponent
- Registration: Use
@RegisterClass(BaseFormComponent, 'EntityName')
decorator - Module Integration: Add to
custom-forms.module.ts
declarations, exports, and import required Kendo modules
Entity & Data Management
- Strong Typing: Never use
any
- always use proper entity types (TemplateEntity
,TemplateCategoryEntity
) - Entity Creation: Use
Metadata.GetEntityObject<EntityType>('EntityName')
pattern - Data Loading: Use
RunView
withResultType='entity_object'
and generic typing - Cache Integration: Leverage engine caches like
TemplateEngineBase.Instance.TemplateContentTypes
Angular Best Practices
- Modern Syntax: Always use
@if
,@for
,@switch
instead of structural directives - Track Functions: Include
track
in@for
loops for performance - Component Integration: Use Kendo UI components for consistency (textbox, textarea, dropdownlist, combobox, numerictextbox, button)
Save Lifecycle & Validation
- Override SaveRecord(): Handle complex saving by overriding
SaveRecord(StopEditModeAfterSave: boolean)
- Related Entity Creation: Create related entities (categories) BEFORE calling
super.SaveRecord()
- Duplicate Prevention: Implement validation like
trim().toLowerCase()
comparison for category names - Error Handling: Use
MJNotificationService.Instance.CreateSimpleNotification()
for user feedback - State Management: Respect
EditMode
state, implement proper change tracking
UI/UX Patterns
- Layout: Use
mjFillContainer
directive withbottomMargin
for proper container sizing - Form Fields: Use
mj-form-field
for individual fields; avoid problematicmj-form-section
properties - Responsive Design: CSS Grid and Flexbox for layouts
- Visual Feedback: Implement hover effects, loading states, progress indicators
- Smart Controls: Conditional displays (e.g., show "New" badge for unsaved records, content type names for saved)
Development Workflow
- Package Building: Always run
npm run build
in specific package directory for TypeScript checking - Workspace Management: Never
npm install
in package directories - always at repo root - Dependencies: Add to individual package.json, then
npm install
at root - Styling: Add custom CSS to
src/shared/form-styles.css
Advanced Features Implemented
- Dynamic Content Management: Multiple related entities (Template Contents) with priority-based ordering
- Type-Safe Dropdowns: Filter invalid options, auto-select defaults
- Smart Validation: Prevent duplicates with normalized comparisons
- User Feedback: Comprehensive notification system for success/warning/error states
- State Synchronization: Proper coordination between main entity and related entity saves
Common Patterns & Anti-Patterns
✅ Do:
- Use strong typing throughout
- Respect MemberJunction entity patterns
- Implement comprehensive error handling
- Provide clear user feedback
- Follow modern Angular syntax
❌ Avoid:
- Using
any
types - Bypassing
Metadata.GetEntityObject()
- Ignoring
EditMode
state - Using outdated Angular syntax
- Running
npm install
in package directories - Creating duplicate entities without validation
Forms Structure
Each entity form typically follows this structure:
- A main form component that extends
BaseFormComponent
- Multiple section components for different aspects of the entity
- A tabbed interface for complex entities
- Integration with grids, dropdowns, and other UI components
Key Components
Component | Description |
---|---|
Entity forms | Forms for managing metadata entities (Entity, EntityField, etc.) |
Action forms | Forms for managing actions and workflows |
User forms | Forms for user management and permissions |
Integration forms | Forms for external system integrations |
AI-related forms | Forms for AI models, prompts, and agents |
Content forms | Forms for content management |
Communication forms | Forms for messaging and notifications |
Notes
- Form components are dynamically instantiated at runtime based on entity names
- Custom loader functions are used to prevent tree-shaking in production builds
- The package is designed to work with the MemberJunction Explorer application
- Forms rely on metadata from the
@memberjunction/core
package for field definitions
Dependencies
- @angular/common
- @angular/core
- @angular/forms
- @memberjunction/core
- @memberjunction/core-entities
- @memberjunction/ng-explorer-core
- @memberjunction/ng-base-forms
- @memberjunction/ng-form-toolbar
- @memberjunction/ng-tabstrip
- @memberjunction/ng-container-directives
- @memberjunction/ng-code-editor
- @memberjunction/ng-timeline
- @memberjunction/ng-join-grid
- @progress/kendo-angular-grid
- @progress/kendo-angular-dropdowns
8 months ago
4 months ago
8 months ago
6 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
6 months ago
6 months ago
5 months ago
8 months ago
8 months ago
8 months ago
6 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
5 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
9 months ago
5 months ago
9 months ago
9 months ago
9 months ago
9 months ago
8 months ago
7 months ago
5 months ago
9 months ago
9 months ago
5 months ago
5 months ago
8 months ago
8 months ago
7 months ago
9 months ago
9 months ago
5 months ago
5 months ago
8 months ago
8 months ago
5 months ago
6 months ago
10 months ago
5 months ago
8 months ago
4 months ago
10 months ago
6 months ago
11 months ago
10 months ago
11 months ago
6 months ago
11 months ago
4 months ago
8 months ago
8 months ago
12 months ago
6 months ago
6 months ago
8 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago