0

using Angular 2.1.0... I am working on an directive that, when applied to textboxes displays an "X" in the right of the textbox, This "X" when clicked, should delete the text from the textbox and clear the model, similar to this angularjs repo https://github.com/amageed/angular-resetfield.

My issue is that I can pass the input value to the directive but I cannot get the model to clear. Now on my clearFunction I am getting: TypeError: Cannot read property 'emit' of undefined

I recognize that I may be going at this in a completely wrong approach and I am open to any suggestions.

Here is how I originally plan to use it in the html:

<input type="text" placeholder="Search" [(ngModel)]="filterText" [(inputClear)]="filterText">

Here is my directive:

@Directive({
/* tslint:disable */
selector: '[inputClear]',
exportAs: 'inputClear'
})

export class inputClearDirective implements OnInit, OnChanges {

@Input() inputClear: any;
@Output() inputClearChange = new EventEmitter();
constructor(private renderer: Renderer, private el: ElementRef) {
}

ngOnChanges(change) {
    console.log('val', this.inputClear);
    if (this.inputClear) {
        console.log('show');
        this.showElement();
    }
    if (!this.inputClear) {
        this.hideElement();
        console.log('hide');
    }
}
//on Init add x to text box
ngOnInit() {
    let me = this.el.nativeElement as HTMLInputElement;
    if (me.nodeName.toUpperCase() !== 'INPUT') {
        throw new Error('Invalid input type for clearableInput:' + me);
    }
    let wrapper = document.createElement('span') as HTMLSpanElement;
    let searchIcon = document.createElement('i') as HTMLElement;
    searchIcon.id = 'searchIcon';

    // // calls the clearvalue function
    searchIcon.addEventListener('click', this.clearValue);

    ////clears the textbox but not the model
    // searchIcon.addEventListener('click', function () {
    //     console.log('clicked');
    //     let inp = this.parentElement.previousSibling as HTMLInputElement;
    //     if (inp && inp.value.length) {

    //         inp.value = '';
    //     }

    // });
    wrapper.setAttribute('style', 'margin-left: -37px;position: relative; margin-right:37px;');

    searchIcon.setAttribute('style', 'display:none');
    searchIcon.className = 'fa fa-times fa-1x';
    wrapper.appendChild(searchIcon);
    wrapper.id = 'searchSpan';

    me.insertAdjacentElement('afterend', wrapper);
}

showElement() {
    let searchIcon = document.getElementById('searchIcon');
    if (searchIcon) {
        searchIcon.removeAttribute('style');
    }
}

hideElement() {
    let searchIcon = document.getElementById('searchIcon');
    if (searchIcon) {
        searchIcon.setAttribute('style', 'display:none');
    }
}

clearValue() {
    console.log('clicked');
    this.inputClear = '';
    this.inputClearChange.emit(this.inputClear);
}
}

Edit: the effect I am after is something like this: enter image description here

for re-usability, I was trying to create an attribute directive to handle this all rolled up.

Jay Culpepper
  • 547
  • 10
  • 25
  • This line `searchIcon.addEventListener('click', this.clearValue);` should be `searchIcon.addEventListener('click', () => this.clearValue());` – admax Feb 21 '17 at 21:09

1 Answers1

1

You can make something really elaborate if you want, but what about this:

<input #searchBox id="search-box" placeholder="Search"/>
<button (click)="searchBox.value = null">
    X
</button>
mickdev
  • 2,765
  • 11
  • 15
  • Thanks for the reply. I have updated my question. I understand I can do it like you suggest, but I am trying to achieve a particular look while making it easy to clear out a textbox. It seemed to me to fall in-line with an attribute directive. – Jay Culpepper Feb 21 '17 at 20:42
  • 1
    The effect you want is just a css styling. Here is an example with bootstrap 3 : http://stackoverflow.com/a/22375617/7447071 Even though you create a directive, you'll have to do the same styling to get the desired effect. Anyway, you can create a directive but you have a fallback here if needed :) – mickdev Feb 21 '17 at 20:55