Attribute directive with ngModel to change field value
update
This approach doesn't work properly. See @RyanHow's answer for a better solution.
original
@Directive({
selector: '[ngModel][uppercase]',
providers: [NgModel],
host: {
'(ngModelChange)' : 'onInputChange($event)'
}
})
export class UppercaseDirective{
constructor(private model:NgModel){}
onInputChange(event){
this.model.valueAccessor.writeValue(event.toUpperCase());
}
}
Plunker
Although Günter's answer looks promising, there is a bug in that the final value in the model has the last entered letter in lowercase.
See here:
https://plnkr.co/edit/SzxO2Ykg2pKq1qfgKVMH
Please use the answer provided in the question. It works correctly.
@Directive({
selector: '[ngModel][uppercase]',
host: {
"(input)": 'onInputChange($event)'
}
})
export class UppercaseDirective{
@Output() ngModelChange:EventEmitter<any> = new EventEmitter()
value: any
onInputChange($event){
this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
}
}
https://plnkr.co/edit/oE3KNMCG7bvEj8FV07RV
I have faced the same issue, where I need to create the custom select in Angular with select2. I have created following directive thing to achieve this with attribute directive and ngModel
.
import {ElementRef, Directive, EventEmitter, Output, Input} from '@angular/core';
import {NgModel} from "@angular/forms";
declare let $;
@Directive({
selector: '[custom-select]',
providers: [NgModel]
})
export class CustomSelectComponent{
$eventSelect:any;
@Output() ngModelChange:EventEmitter<any> = new EventEmitter();
@Input() set ngModel(value:any){
//listen to the input value change of ngModel and change in the plugin accordingly.
if(this.$eventSelect){
this.$eventSelect.val(value).trigger('change',{fromComponent:true});
}
}
constructor(private elementRef: ElementRef) {}
ngOnInit(){
this.$eventSelect = $(this.elementRef.nativeElement);
this.$eventSelect.select2({minimumResultsForSearch:-1});
this.$eventSelect.on("change.select2", (event,data)=> {
//listen to the select change event and chanage the model value
if(!data || !data.fromComponent){ //dont change model when its chagned from the input change event
this.ngModelChange.emit(this.$eventSelect.val());
}
});
}
}
with following usage
<select custom-select [(ngModel)]="protocol.type">
<option value="1">option1</option>
<option value="1">option2</option>
</select>