фокусировка ng-select вход фильтра при раскрывающемся списке - PullRequest
3 голосов
/ 22 мая 2019

Я использую ng-select и у меня есть определенный шаблон заголовка фильтра, который содержит входные данные.

Я бы хотел, чтобы ввод получал фокус при открытии раскрывающегося списка для выбора, но я не могу понять, как это сделать.

У меня есть пример здесь -> https://stackblitz.com/edit/angular-playground-f57jog

Я попытался подключиться к выводу ng-select (open) и вызвать focus() на моем элементе ввода, но мне это не удалось.

Какой правильный подход здесь? Спасибо

Ответы [ 5 ]

4 голосов
/ 24 мая 2019

Я бы создал специальную директиву и использовал бы ее везде, где мне это нужно:

@Directive({
  selector: '[appAutofocus]'
})
export class AutofocusDirective implements OnInit {

  constructor(private el: ElementRef) {
  }

  ngOnInit() {
    this.el.nativeElement.focus();
  }
}

html

<input appAutofocus ... />

Так что она должна работать в Chrome, Firefox,и т.д.

1 голос
/ 31 мая 2019

Вы можете использовать этот метод:

в вашем html:

<ng-select #api [items]="cars"
          [virtualScroll]="true"
          [loading]="loading"
          bindLabel="brand"
          bindValue="id"
          (scroll)="onScroll($event)"
          (scrollToEnd)="onScrollToEnd()"
          [dropdownPosition]="'bottom'"
          [searchable]="false"
          [(ngModel)]="selectedCar2"
          [searchFn]="customSearchFn"
          (change)="onChange($event)"
          (open)="focusInputField()">

обратите внимание, что (открыто) изменилось.

в вашем файле .ts вы добавляете:

    @ViewChild('filterInput') filterInput:ElementRef;


    focusInputField() {
      setTimeout(() => {
      this.filterInput.nativeElement.focus()
      }, 10)
    }

Это должно работать как для Chrome, так и для Firefox.

0 голосов
/ 31 мая 2019

Существует проблема синхронизации между моментом запуска обратного вызова ng-select и элементом filterInput.Ваш синтаксис правильный, но filterInput не определен, когда выбрано ng-select open.Обратитесь к следующей ошибке в консоли отладки в предоставленном стеке:задержать вызов фокуса на неопределенном элементе в открытом обратном вызове.Ниже я только что сделал это путем 1) захвата filterInput ElementRef через @ViewChild, 2) рефакторинга вашей текущей логики фокуса в метод внутри компонента и добавление задержки 250 мс, и 3) вызова указанного метода с использованием открытого компонента ng-selectЭмитент событий.Я также предоставил альтернативу RxJS шагу 2.


app.component.ts

// 1
@ViewChild('filterInput') filterInput: ElementRef;

// 2
setFilterFocus() {
  setTimeout((() => { this.filterInput.nativeElement.focus() }).bind(this), 250)
}

app.component.html

<!-- 3 -->
<ng-select #api [items]="cars"
          [virtualScroll]="true"
          [loading]="loading"
          bindLabel="brand"
          bindValue="id"
          (scroll)="onScroll($event)"
          (scrollToEnd)="onScrollToEnd()"
          [dropdownPosition]="'bottom'"
          [searchable]="false"
          [(ngModel)]="selectedCar2"
          [searchFn]="customSearchFn"
          (change)="onChange($event)"
          (open)="setFilterFocus()">

Повторный шаг 2 - вместо этого используется RxJS

app.component.ts дополнительный импорт

import { of } from 'rxjs';
import { delay, tap } from 'rxjs/operators';

app.component.ts setFilterFocus RxJS style

setFilterFocus() {
    of(null)
      .pipe(
        delay(250), 
        tap(() => this.filterInput.nativeElement.focus()))
      .subscribe();
}
0 голосов
/ 30 мая 2019

Просто используйте ViewChildren и подпишите изменения, затем сосредоточьтесь. Это.

@ViewChildren('filterInput') filterInput : QueryList<ElementRef>;

onOpen()
{
  this.filterInput.changes.subscribe(res=>{
      this.filterInput.first.nativeElement.focus()
  })
}

А в вашем .html

<ng-select ...  (open)="onOpen()"></ng-select>

См. Ваш разветвленный стек

0 голосов
/ 24 мая 2019

Добавьте атрибут autofocus к вашему тегу input

Ваш код будет выглядеть следующим образом:

<input autofocus #filterInput style="width: 100%; line-height: 24px" type="text" (input)="api.filter($event.target.value)"/>

Обновленная версия вашей демонстрации stackbliz здесь

Надеюсь, это поможет:)

...