Angular formly 5.10.3 custom toggle event on change

3.7k Views Asked by At

I have a working custom template in formly with an ionic toggle bethen two texts. How can I catch the change event? this is a reduced code example:

Custom formly idea:

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

@Component({
 selector: 'formly-field-input',
 template: `
   <span class="toggleContainer">
      <p [class]="to.checked ? '' : 'toggleSelected'"> {{ to.textBefore }} </p>
      <ion-toggle 
        [checked]="to.checked" 
        [disabled]="to.disabled" 
        color="primary">
      </ion-toggle>
      <p [class]="to.checked ? 'toggleSelected' : ''"> {{ to.textAfter }} </p>
   </span>
 `,
 styleUrls: ['./toggle-2-labels.component.scss'],
})
export class toggle2LabelsComponent extends FieldType { }

Imput added to form:

 {
    key: 'exampleName',
    type: 'toggle2Labels',
    wrappers: ['acc-wrapper'],
    templateOptions: {
        disabled: true,
        checked: false,
        textBefore: 'something',
        textAfter: 'something',
        onChange: (field, value) => console.log('onChange'),
        change: (field, $event) => {
            console.log('change');
        },
    },
    hooks: {
        onInit: (field: FormlyFieldConfig) => {
            //Other stuff
        },
    }
 },

I tried with onChange and change events without working. I think that could be a problem of not having an value itself, but I don't know how to add it to my custom toggle. Maybe any kind of method to get an attributes like to.checked change would be fine. Any idea?

3

There are 3 best solutions below

0
On BEST ANSWER

Finally I got it, formly onChange and change events doesn't works for custom imputs (they doesn't works with the formly guide example too) so the solution for me was getting the (ionChange) event on the custom imput template with a hook on init like the example;

Custom formly:

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

@Component({
 selector: 'formly-field-input',
 template: `
   <span class="toggleContainer">
      <p [class]="to.checked ? '' : 'toggleSelected'"> {{ to.textBefore }} </p>
      <ion-toggle 
        <ion-toggle 
          [formControl]="formControl" 
          [formlyAttributes]="field"
          [value]="to.checked"
          [checked]="to.checked" 
          [disabled]="to.disabled" 
          (ionChange)="formControl.setValue(to.checked)"
        color="primary">
        color="primary">
      </ion-toggle>
      <p [class]="to.checked ? 'toggleSelected' : ''"> {{ to.textAfter }} </p>
   </span>
 `,
 styleUrls: ['./toggle-2-labels.component.scss'],
})
export class toggle2LabelsComponent extends FieldType { }

Custom imput

{
    key: 'exampleName',
    type: 'toggle2Labels',
    wrappers: ['acc-wrapper'],
    templateOptions: {
        disabled: true,
        checked: false,
        textBefore: 'something',
        textAfter: 'something',
        onChange: (field, value) => console.log('onChange'),
        change: (field, $event) => {
            console.log('change');
        },
    },
    hooks: {
        onInit: (field: FormlyFieldConfig) => {
            field.formControl.valueChanges.subscribe(() => {
                console.log('only works here for me');
            });
        },
    }
 },
1
On

The attribute you need is called ionChange. Since this is an ionic framework element, simply using the convention defaults is not assured of working.

template: `
   <span class="toggleContainer">
      <p [class]="to.checked ? '' : 'toggleSelected'"> {{ to.textBefore }} </p>
      <ion-toggle 
        (ionChange)="() => console.log('onChange')"
        [checked]="to.checked" 
        [disabled]="to.disabled" 
        color="primary">
      </ion-toggle>
      <p [class]="to.checked ? 'toggleSelected' : ''"> {{ to.textAfter }} </p>
   </span>
 `,
1
On

Html file

<span class="toggleContainer">
      <p [class]="to.checked ? '' : 'toggleSelected'">{{ to.textBefore }}</p>
      <ion-toggle
        (ionChange)="changeToggle($event)"
        [checked]="to.checked"
        [disabled]="to.disabled"
        color="primary"
      >
      </ion-toggle>
      <p [class]="to.checked ? 'toggleSelected' : ''">{{ to.textAfter }}</p>
    </span>

ts File

public to = {
    checked: false,
    disabled: false,
    textBefore: 'something',
    textAfter: 'something'
  };
  changeToggle(event: any) {
    console.log(event.value);
    this.to.checked = event.value;
  }