Search code examples
angular-materialjsonschemaangular-formlyangular-cli-v8

Angular CLI 8 - Formly custom select for JSON schema (draft 4)


I've got some difficulties getting my JSON schema (draft 4) to fully work with Angular-Formly forms custom templates. I've made several templates for various data types and I'm stuck with a template for a dropdown menu using the select tag in Angular CLI. I've found lots of examples on how to make a select component for newer JSON schemas but not for older schemas where enum (see: my JSON part) is used for selections.

Here is my JSON part:

"hardware": {
    "type": "object",
    "title": "hw.net",
    "properties": {
        "network-0": {
            "type": "string",
            "title": "hw.net.types",
            "enum": [
                "dhcp",
                "static"
            ],
            "default": "dhcp"
        }
    }
}

Here is my approach in Angular:

import { Component } from '@angular/core';
import { FieldType } from '@ngx-formly/core'; 

@Component({
  selector: 'formly-enum-type',
  template: `
    <mat-label *ngIf="to.label">{{ to.label | translate }}</mat-label>
    <mat-select [formControl]="formControl" [formlyAttributes]="field" (selectionChange)="to.change && to.change(field, formControl)">
      <ng-container *ngFor="let item of to.options">
        <mat-option [value]="item">{{ item }}</mat-option>
      </ng-container>
    </mat-select>
  `,
})

export class EnumTypeComponent extends FieldType { }

Unexpected result:

unexpected result

My script is obviously somewhat incomplete or even wrong. I'm trying to figure out, how to correctly load the 'enum' part into my 'option' tag. Current result is a dropdown menu with objects instead of text. Please keep in mind, this JSON schema is created using the http://json-schema.org/draft-4/schema# and it must remain this way.


Solution

  • Was able to solve this using the json pipe feature {{ item | json }} to see what was inside my object. After that I was able to fix my script so objects items got displayed properly.

    Here is my fixed component if anyone ever needs something similar done.

    @Component({
      selector: 'formly-enum-type',
      template: `
        <mat-label *ngIf="to.label">{{ to.label | translate }}</mat-label>
        <mat-select [formControl]="formControl" [formlyAttributes]="field" (selectionChange)="to.change && to.change(field, formControl)">
          <ng-container *ngFor="let item of to.options">
            <mat-option [value]="item.value">{{ item.label }}</mat-option>
          </ng-container>
        </mat-select>
      `,
    })
    
    export class EnumTypeComponent extends FieldType { }