<!DOCTYPE html>
<html>

  <head>
    <base href="." />
    <title>ng-formly example</title>
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" integrity="sha384-2hfp1SzUoho7/TsGGGDaFdsuuDL0LX2hnUp6VkX3CUQ2K4K+xjboZdsXyp4oUHZj" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
    <script data-require="lodash.js@4.16.2" data-semver="4.16.2" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.js"></script>
    <script src="https://unpkg.com/zone.js@0.6.26/dist/zone.js"></script>
    <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

  <body>
    <formly-demo-app>
    loading...
    </formly-demo-app>
  </body>

</html>
pre {
            display: block;
            padding: 9.5px;
            margin: 0 0 10px;
            font-size: 13px;
            line-height: 1.42857143;
            color: #333;
            word-break: break-all;
            word-wrap: break-word;
            background-color: #f5f5f5;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        .c-select {
            display: block;
            width: 100%;
        }

        /* Checkbox Toggle */

        .checkbox-toggle {
            margin: 0;
            padding: 0;
        }

        .checkbox-toggle input[type="checkbox"] {
            display: none;
        }
        .checkbox-toggle input[type="checkbox"]:checked + label {
            border-color: #0275D8;
            background: #0275D8;
            box-shadow: inset 0 0 0 20px #0275D8;
        }
        .checkbox-toggle input[type="checkbox"]:checked + label.toggle-alert {
            border-color: #f10000;
            background: #f10000;
            box-shadow: inset 0 0 0 20px #f10000;
        }
        .checkbox-toggle label {
            -webkit-transition: all .2s ease-in-out;
            transition: all .2s ease-in-out;
            display: inline-block;
            position: relative;
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            background: #ECEEEF;
            box-shadow: inset 0 0 0 0 #0275D8;
        }
        .checkbox-toggle label div {
            -webkit-transition: all .2s ease-in-out;
            transition: all .2s ease-in-out;
            background: white;
            width: 30px;
            height: 30px;
            border-radius: 50%;
        }
        .checkbox-toggle--large label div {
          width: 41px;
          height: 41px;
        }
        .checkbox-toggle label:hover, .checkbox-toggle label > div:hover {
            cursor: pointer;
        }
        .checkbox-toggle input[type="checkbox"]:checked + label > div {
            margin-left: 36px;
        }
        .checkbox-toggle--large input[type="checkbox"]:checked + label > div {
            margin-left: 55px;
        }
        .checkbox-toggle label {
            border: 2px solid #ECEEEF;
            border-radius: 42px;
            height: 34px;
            width: 70px;
        }
        .checkbox-toggle--large label {
          width: 100px;
          height: 45px;
        }
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    
    '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
    'ng-formly': 'npm:ng-formly/bundles/ng-formly.umd.min.js',
    'rxjs': 'npm:rxjs',
    'typescript': 'npm:typescript@2.0.2/lib/typescript.js',
    'lodash': 'npm:lodash/cloneDeep.js'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
//main entry point
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
import { NgModule, Component, enableProdMode, OnInit } from '@angular/core';
import { FormsModule, ReactiveFormsModule, Validators, FormBuilder, FormGroup, FormControl } from '@angular/forms';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { FormlyModule, FormlyFieldConfig, FormlyBootstrapModule } from 'ng-formly';
import { DynamicFormlyFieldBuilder } from './dynamic-formly-field.builder';
import { FormlyFieldTemplate } from './template';

@Component({
  selector: 'formly-demo-app',
  templateUrl: './template.html',
})
export class FormlyDemoApp implements OnInit {
  author = { name: 'Tony Franzese', url: 'https://github.com/franzeal' };
  
  form: FormGroup;
  model: any;
  options: any;
  fields: FormlyFieldConfig[];
  
  constructor() { 
  }
  
  ngOnInit(): void {
    this.form = new FormGroup({});
    this.model = {};
    this.fields = [
      {
        type: 'template'
        templateOptions: {
          template: `The current time is {{time | date:'M/d/yyyy HH:mm:ss'}}`;
        },
        lifecycle: {
          onInit: function() {
            
            setInterval(() => this.time = new Date(), 1000);
          }
        }
      }
    ];
    this.options = {};
  }
}

@NgModule({
  declarations: [
    FormlyDemoApp,
    FormlyFieldTemplate
  ],
  imports: [
    BrowserModule,
    FormlyModule.forRoot({
      types: [
        { 
          name: 'template', 
          component: FormlyFieldTemplate
        }
      ]
    }),
    FormlyBootstrapModule,
    FormsModule,
    ReactiveFormsModule,
  ],
  providers: [DynamicFormlyFieldBuilder],
  bootstrap: [FormlyDemoApp]
})
export class AppModule {
}

<div class="container">
    <h1>ng-formly example: Dynamically compiled templates</h1>
    <p>This is an example to demonstrate using dynamically compiled templates in formly forms.</p>
    <hr>
    <form class="formly" role="form" novalidate [formGroup]="form">
        <formly-form [form]="form" [fields]="fields" [model]="model" [options]="options">
        </formly-form>
    </form>
    <hr>
    <br><strong>Form Data:</strong><br><pre>{{model | json}}</pre><br>
    <hr>

    <div style="margin-top:30px">
        <small>
          This is an example for the
          <a href="https://formly-js.github.io/ng2-formly">ng-formly</a>
          project made with ♥ by
          <strong>
            <span *ngIf="!author.name || !author.url">
              {{author.name || 'anonymous'}}
            </span>
            <a *ngIf="author.url" href="{{author.url}}">
              {{author.name}}
            </a>
          </strong>
        </small>
    </div>
</div>
import { Compiler, Component, ComponentFactory, forwardRef, NgModule, Injectable } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormlyModule, FieldType } from 'ng-formly';


/** [source]{@link http://stackoverflow.com/questions/34784778/equivalent-of-compile-in-angular-2/37044960#37044960} */
@Injectable()
export class DynamicFormlyFieldBuilder {
    constructor(
        private compiler: Compiler
    ) { }

    private factoryCache: { [templateKey: string]: ComponentFactory<FieldType> } = {};

    public createComponentFactory(template: string): Promise<ComponentFactory<FieldType>> {
        let factory = this.factoryCache[template];
        if (factory) {
            return Promise.resolve(factory);
        }

        let type = this.createDynamicFormlyField(template);
        let module = this.createComponentModule(type);
        return new Promise(resolve => {
            this.compiler
                .compileModuleAndAllComponentsAsync(module)
                .then(moduleWithFactories => {
                    factory = _.find(moduleWithFactories.componentFactories, { componentType: type });
                    this.factoryCache[template] = factory;
                    resolve(factory);
                });
        });
    }

    private createDynamicFormlyField(template: string) {

        @Component({
            selector: 'dynamic-formly-field',
            template: template,
        })
        class DynamicFormlyField extends FieldType {
        };

        return DynamicFormlyField;
    }

    private createComponentModule(componentType: any) {
        // Import any modules that export components/directives/pipes your 
        // templates need access to
        @NgModule({
            imports: [
                CommonModule,
                FormsModule,
                ReactiveFormsModule
            ],
            declarations: [
                componentType
            ]
        })

        class RuntimeComponentModule { }

        return RuntimeComponentModule;
    }
}

import { AfterViewInit, Component, ComponentRef, DoCheck, OnDestroy, OnInit, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core';
import { FieldType } from 'ng-formly';
import { DynamicFormlyFieldBuilder } from './dynamic-formly-field.builder';


/** [source]{@link http://stackoverflow.com/questions/34784778/equivalent-of-compile-in-angular-2/37044960#37044960} */
@Component({
    selector: 'formly-field-template',
    template: `
        <template #dynamicFieldComponent></template>
    `
})
export class FormlyFieldTemplate extends FieldType implements AfterViewInit, OnDestroy, OnInit {
    @ViewChild('dynamicFieldComponent', { read: ViewContainerRef }) dynamicFieldComponent: ViewContainerRef;
    protected componentRef: ComponentRef<FieldType>;

    protected viewInitialized = false;

    constructor(
        private dynamicFormlyFieldBuilder: DynamicFormlyFieldBuilder
    ) {
        super();
    }

    get template(): string {
        return _.isString(this.to["template"]) ? this.to["template"] : '';
    }

    protected refreshContent() {
        if (this.componentRef) {
            this.componentRef.destroy();
        }

        this.dynamicFormlyFieldBuilder
            .createComponentFactory(this.template)
            .then(factory => {
                this.componentRef = this
                    .dynamicFieldComponent
                    .createComponent(factory);

                Object.assign(this.componentRef.instance, {
                    model: this.model,
                    form: this.form,
                    field: this.field,
                    options: this.options
                });
            });
    }

    ngAfterViewInit(): void {
        this.viewInitialized = true;
        this.refreshContent();
    }

    ngOnChanges(changes: SimpleChanges): void {
        if (!this.viewInitialized) {
            return;
        }

        this.refreshContent();
    }

    ngOnDestroy() {
        if (this.componentRef) {
            this.componentRef.destroy();
            this.componentRef = undefined;
        }
    }
}