import {NgModule,Component,ElementRef,AfterViewInit,AfterViewChecked,OnChanges,Input,forwardRef,EventEmitter,Output} from '@angular/core';
import {CommonModule} from '@angular/common';
import {NG_VALUE_ACCESSOR,ControlValueAccessor} from '@angular/forms';
import {DomHandler} from '../dom/domhandler';
export const INPUTSWITCH_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputSwitch),
multi: true
};
@Component({
selector: 'p-inputSwitch',
template: `
`,
providers: [INPUTSWITCH_VALUE_ACCESSOR,DomHandler]
})
export class InputSwitch implements ControlValueAccessor,AfterViewInit,AfterViewChecked {
@Input() onLabel: string = 'On';
@Input() offLabel: string = 'Off';
@Input() disabled: boolean;
@Input() style: any;
@Input() styleClass: string;
@Input() tabindex: number;
@Input() inputId: string;
@Input() ariaLabelTemplate: string = "InputSwitch {0}";
@Output() onChange: EventEmitter = new EventEmitter();
checked: boolean = false;
focused: boolean = false;
onModelChange: Function = () => {};
onModelTouched: Function = () => {};
public container: any;
public handle: any;
public onContainer: any;
public offContainer: any;
public onLabelChild: any;
public offLabelChild: any;
public offset: any;
public ariaLabel: string;
public ariaLabelledBy: string;
initialized: boolean = false;
constructor(public el: ElementRef, public domHandler: DomHandler) {}
ngAfterViewInit() {
this.container = this.el.nativeElement.children[0];
this.handle = this.domHandler.findSingle(this.el.nativeElement, 'div.ui-inputswitch-handle');
this.onContainer = this.domHandler.findSingle(this.container,'div.ui-inputswitch-on');
this.offContainer = this.domHandler.findSingle(this.container,'div.ui-inputswitch-off');
this.onLabelChild = this.domHandler.findSingle(this.onContainer,'span.ui-inputswitch-onlabel');
this.offLabelChild = this.domHandler.findSingle(this.offContainer,'span.ui-inputswitch-offlabel');
}
ngAfterViewChecked() {
if(this.container && this.container.offsetParent && !this.initialized) {
this.render();
}
}
render() {
let onContainerWidth = this.domHandler.width(this.onContainer),
offContainerWidth = this.domHandler.width(this.offContainer),
spanPadding = this.domHandler.innerWidth(this.offLabelChild) - this.domHandler.width(this.offLabelChild),
handleMargins = this.domHandler.getOuterWidth(this.handle) - this.domHandler.innerWidth(this.handle);
var containerWidth = (onContainerWidth > offContainerWidth) ? onContainerWidth : offContainerWidth,
handleWidth = containerWidth;
this.handle.style.width = handleWidth + 'px';
handleWidth = this.domHandler.width(this.handle);
containerWidth = containerWidth + handleWidth + 6;
var labelWidth = containerWidth - handleWidth - spanPadding - handleMargins;
this.container.style.width = containerWidth + 'px';
this.onLabelChild.style.width = labelWidth + 'px';
this.offLabelChild.style.width = labelWidth + 'px';
//position
this.offContainer.style.width = (this.domHandler.width(this.container) - 5) + 'px';
this.offset = this.domHandler.width(this.container) - this.domHandler.getOuterWidth(this.handle);
//default value
if(this.checked) {
this.handle.style.left = this.offset + 'px';
this.onContainer.style.width = this.offset + 'px';
this.offLabelChild.style.marginRight = -this.offset + 'px';
}
else {
this.onContainer.style.width = 0 + 'px';
this.onLabelChild.style.marginLeft = -this.offset + 'px';
}
this.initialized = true;
}
toggle(event,checkbox) {
if(!this.disabled) {
if(this.checked) {
this.checked = false;
this.uncheckUI();
}
else {
this.checked = true;
this.checkUI();
}
this.onModelChange(this.checked);
this.onChange.emit({
originalEvent: event,
checked: this.checked
});
checkbox.focus();
}
}
checkUI() {
this.onContainer.style.width = this.offset + 'px';
this.onLabelChild.style.marginLeft = 0 + 'px';
this.offLabelChild.style.marginRight = -this.offset + 'px';
this.handle.style.left = this.offset + 'px';
this.updateAriaLabel();
}
uncheckUI() {
this.onContainer.style.width = 0 + 'px';
this.onLabelChild.style.marginLeft = -this.offset + 'px';
this.offLabelChild.style.marginRight = 0 + 'px';
this.handle.style.left = 0 + 'px';
this.updateAriaLabel();
}
onFocus(event) {
this.focused = true;
}
onBlur(event) {
this.focused = false;
this.onModelTouched();
}
writeValue(checked: any) : void {
this.checked = checked;
if(this.initialized) {
if(this.checked === true)
this.checkUI();
else
this.uncheckUI();
}
}
registerOnChange(fn: Function): void {
this.onModelChange = fn;
}
registerOnTouched(fn: Function): void {
this.onModelTouched = fn;
}
setDisabledState(val: boolean): void {
this.disabled = val;
}
updateAriaLabel() {
let pattern = /{(.*?)}/,
value = this.checked ? this.onLabel : this.offLabel;
this.ariaLabel = this.ariaLabelTemplate.replace(this.ariaLabelTemplate.match(pattern)[0], value);
}
}
@NgModule({
imports: [CommonModule],
exports: [InputSwitch],
declarations: [InputSwitch]
})
export class InputSwitchModule { }