Skip to content

Instantly share code, notes, and snippets.

@7freaks-otte
Last active April 17, 2021 06:12
Show Gist options
  • Save 7freaks-otte/d46bbc2a0c5ad25d1468e3fbb8b0acff to your computer and use it in GitHub Desktop.
Save 7freaks-otte/d46bbc2a0c5ad25d1468e3fbb8b0acff to your computer and use it in GitHub Desktop.
Short-term workaround until ionic2 <ion-toggle> ionChange events are fixed
import {Component, EventEmitter, Optional} from '@angular/core';
import {ControlValueAccessor, NgControl} from '@angular/forms';
import {Item} from 'ionic-angular';
/*
* ion-toggle replacement written by Michael Otte (7freaks.com) in order to
* - prevent ionChange events on setting ngModel https://github.com/driftyco/ionic/issues/7806
* - emit (change) event only if user interaction has taken place
*
* Usage:
* <sf-toggle item-content color="secondary" [disabled]="someVal" [(ngModel)]="value" (change)="onChange($event)"></sf-toggle>
* Don't forget to add this to your app.module.ts
* import { SfToggle } from './sf-toggle.component';
* @NgModule({
* declarations: [ SfToggle, ... ]
*
* Note: - "item-content" directive is needed to display this in ion-items
* - event is named "change" instead of ionChange
* - I did't implement [checked] just because I don't need it and hacked this as short-term workaround until ion-toggle is fixed
* - Feel free to use the code, MIT licensed, no warranty, you know...
*/
@Component({
selector: 'sf-toggle',
template:
`<ion-toggle ` +
` [color]="color" ` +
` [disabled]="_disabled" ` +
` [checked]="_value" ` +
` (ionChange)="doChange($event)" ` +
` style="display:block" ` +
`></ion-toggle>`,
host: {
style: 'display: inline-block;'
},
inputs: ['color', 'disabled'],
outputs: ['change']
})
export class SfToggle implements ControlValueAccessor {
color: any;
_value: any;
_disabled = false;
public change = new EventEmitter();
constructor( @Optional() private _item: Item, @Optional() private ngControl: NgControl) {
ngControl && (ngControl.valueAccessor = this);
}
get disabled(): any {return this._disabled;};
set disabled(value: any) {this._disabled = !!value || typeof value == 'string';}
get value(): any {return this._value;};
set value(value: any) {this.writeValue(value);}
writeValue(value: any) {
var tmpVal = !!value;
if (tmpVal !== this._value) {
this._value = tmpVal;
this.changed();
}
}
doChange(event: any) {
if (event.checked !== this._value) { //value has changed, event was triggered through user interaction with toggle
this.writeValue(event.checked);
this.onTouched();
this.change.emit({value: this._value});
} //else nothing has changed, event was triggered through setter from outside
}
changed() {
this.onChange(this._value);
}
ngAfterContentChecked() {
this.setControlCss();
}
setControlCss() {
if (this._item && this.ngControl) {
this._item.setElementClass('ng-untouched', this.ngControl.untouched);
this._item.setElementClass('ng-touched', this.ngControl.touched);
this._item.setElementClass('ng-pristine', this.ngControl.pristine);
this._item.setElementClass('ng-dirty', this.ngControl.dirty);
this._item.setElementClass('ng-valid', this.ngControl.valid);
this._item.setElementClass('ng-invalid', !this.ngControl.valid);
this._item.setElementClass('input-has-value', !this._disabled);
this._item.setElementClass('item-input-disabled', this._disabled);
}
}
onChange = (_) => {};
onTouched = () => {};
registerOnChange(fn: (_: any) => void): void {this.onChange = fn;}
registerOnTouched(fn: () => void): void {this.onTouched = fn;}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment