Last active
April 17, 2021 06:12
-
-
Save 7freaks-otte/d46bbc2a0c5ad25d1468e3fbb8b0acff to your computer and use it in GitHub Desktop.
Short-term workaround until ionic2 <ion-toggle> ionChange events are fixed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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