testing
testing

Reputation: 2343

Cannot `focus` after `blur` from another element in angular2

Consider the following plunker

I have an input that will expand into dropdown when (focus) I want to have the following behavior

  1. When input is focused, user click anywhere that is not in the dropdown or input , dropdown should be contracted
  2. When input is focused, user click on the dropdown, dropdown should stay expanded

Right now when user click on the input and click on the dropdown, the dropdown is contracted.

Here is my code for reference

@Component({
  selector: 'my-app',
  template: `
      <div class="wrapper">
        <input [(ngModel)]="searchText" 
               tabindex="0"
               placeholder="name" 
               (focus)="inputShow()"
               (blur)="inputHide()" 
               >
        <div class="option-wrapper" 
             [hidden]="isHideList()" 
             tabindex="0" 
             (focus)="inputShow()" 
             (blur)="inputHide()">
          <li class="options" 
              *ngFor="#option of optionlist">
            <div >{{option['name']}}</div>
          </li>
        </div>
      </div>
    `
})
export class App {

    optionlist = [{'name': '1'}, {'name': '2'}]

    inputShow() {
      this.inputFocus = true;
    }
    inputHide(){
      this.inputFocus= false;
    }

    isHideList() {
        return !this.inputFocus;
    }
}

One way to get close to the expected behavior is to take away

(blur)="inputHide()"

on input like this

But now when I click on input and click anywhere besides input and dropdown the dropdown does not contract

Only if I click on input then dropdown then anywhere else does the dropdown contract

Can anyone give me some insight on this?

Thanks

Upvotes: 1

Views: 1343

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657366

Plunker example

Listen to window click events and only hide the dropdown when the event.target is outside the wrapper:

@Component({
  selector: 'my-app',
  template: `
      <div #wrapper class="wrapper">
        <input #input [(ngModel)]="searchText" 
               tabindex="0"
               placeholder="name" 
               (focus)="inputShow()"
               > 
        <div class="option-wrapper" 
             [hidden]="isHideList()" 
             tabindex="0" 
             (focus)="inputShow()" 
             > 
          <li class="options" 
              *ngFor="#option of optionlist">
            <div >{{option['name']}}</div>
          </li>
        </div>
      </div>
    `
})
export class App {
    @ViewChild('wrapper') wrapper:ElementRef;
    @ViewChild('input') input:ElementRef;


    @HostListener('window:click', ['$event'])
    clickHandler(event) {

      var parent = event.target;
      while(parent != this.wrapper.nativeElement && parent != document) {
        parent = parent.parentNode;
      }
      if(parent == document) {
        this.inputHide();
      }
    }

    optionlist = [{'name': '1'}, {'name': '2'}]

    inputShow() {
      this.inputFocus = true;
    }
    inputHide(){
      this.inputFocus= false;
    }

    isHideList() {
        return !this.inputFocus;
    }
}

Upvotes: 4

Related Questions