Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sidmohanty11/74a2fb93ce2b512f49bb64020520222c to your computer and use it in GitHub Desktop.
Save sidmohanty11/74a2fb93ce2b512f49bb64020520222c to your computer and use it in GitHub Desktop.
Dynamic HTML tags generation with Angular v16 and above
import {Component, Input, ViewChild, ElementRef, ViewContainerRef, TemplateRef, Renderer2} from '@angular/core';
import {bootstrapApplication} from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
@Component({
selector: 'dynamic-div, DynamicDiv',
template: ` <div #v><ng-content></ng-content></div>`,
standalone: true,
})
export class DynamicDiv {
@ViewChild('v', { read: ElementRef })
v!: ElementRef;
}
@Component({
selector: 'dynamic-h1, DynamicH1',
template: ` <h1 #v><ng-content></ng-content></h1>`,
standalone: true,
})
export class DynamicH1 {
@ViewChild('v', { read: ElementRef })
v!: ElementRef;
}
@Component({
selector: 'dynamic-a, DynamicA',
template: ` <a #v href=""><ng-content></ng-content></a>`,
standalone: true,
})
export class DynamicA {
@ViewChild('v', { read: ElementRef })
v!: ElementRef;
}
@Component({
selector: 'dynamic-button, DynamicButton',
template: ` <button #v><ng-content></ng-content></button>`,
standalone: true,
})
export class DynamicButton {
@ViewChild('v', { read: ElementRef })
v!: ElementRef;
}
@Component({
selector: 'dynamic-renderer',
standalone: true,
template: `
<ng-template #tagTemplate><ng-content></ng-content></ng-template>
<ng-container
*ngComponentOutlet="
Element;
content: myContent
"
></ng-container>
`,
imports: [CommonModule]
})
export class DynamicRenderComponent {
@Input() Tag: any = 'div';
@ViewChild('tagTemplate', { static: true })
tagTemplate!: TemplateRef<any>;
Element = DynamicDiv;
myContent: any;
constructor(private vcRef: ViewContainerRef) {}
ngOnChanges() {
switch(this.Tag) {
case 'div':
this.Element = DynamicDiv;
break;
case 'button':
this.Element = DynamicButton;
break;
case 'a':
this.Element = DynamicA;
break;
case 'h1':
this.Element = DynamicH1;
break;
default:
this.Element = DynamicDiv;
break;
}
this.myContent = [
this.vcRef.createEmbeddedView(this.tagTemplate).rootNodes,
];
}
}
@Component({
selector: 'app-root',
standalone: true,
template: `
<select (change)="onChange($event)">
<option value="div">div</option>
<option value="button">button</option>
<option value="span">span</option>
<option value="p">p</option>
<option value="a">a</option>
<option value="h1">h1</option>
</select>
<dynamic-renderer [Tag]="Tag">Inside {{ Tag }}</dynamic-renderer>
`,
imports: [DynamicRenderComponent]
})
export class PlaygroundComponent {
Tag = 'div'
onChange(event: any) {
this.Tag = event.target.value;
}
}
bootstrapApplication(PlaygroundComponent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment