How can I set focus to another input?

后端 未结 4 1988
天涯浪人
天涯浪人 2020-12-08 04:55

I need to be able to switch focus to an input element when some event occurs. How do I do that in Angular 2?

For example:



        
相关标签:
4条回答
  • 2020-12-08 05:07

    Actually you don't need to write any TS code for that (I'm using one of the other answer's example):

    <input (keyup.enter)="focusable.focus()"/>
    <input #focusable /> 
    
    0 讨论(0)
  • 2020-12-08 05:17

    You can do this just passing the second input as a variable to the first one

    For example

    HTML

    <!-- We pass focusable as a parameter to the processKeyUp function -->
    <input (keyup)="processKeyUp($event, focusable)"/>
    
    <!-- With #focusable we are creating a variable which references to the input -->
    <input #focusable /> 
    

    Later in your js/ts

    @Component({
      selector: 'plunker-app'
    })
    @View({
      templateUrl: 'main.html'
    })
    class PlunkerApp {
    
      constructor() {
      }
    
      processKeyUp(e, el) {
        if(e.keyCode == 65) { // press A
          el.focus();
        }
      }
    }
    

    el is the raw element, so you can use pure javascript on it.

    Here's a plnkr so you can see it working.

    I hope it helps.

    0 讨论(0)
  • 2020-12-08 05:20

    Set focus - Angular 2/5

    <input type="text" [(ngModel)]="term2" #inputBox>
    
    import { Component, ViewChild, ElementRef } from '@angular/core';
    
    @Component({
      selector: 'app-general',
      templateUrl: './general.component.html',
      styleUrls: ['./general.component.scss']
    })
    export class GeneralComponent {
    
      @ViewChild("inputBox") _el: ElementRef;
    
      setFocus() {
        this._el.nativeElement.focus();
      }
    }
    

    For setting focus on load

    ngAfterViewInit() {
        this._el.nativeElement.focus();
      }
    

    You can update this logic accordingly for key press.

    More Info

    0 讨论(0)
  • 2020-12-08 05:22

    For manipulation on DOM elements always try to use Directives. In this case you are able to write simple directive.

    For accessing DOM from directive we can inject reference of our host DOM element by the ElementRef in directive constructor.

    constructor(@Inject(ElementRef) private element: ElementRef) {}
    

    For change detection of binded value we can use ngOnChanges livecycle method.

    protected ngOnChanges() {}
    

    All other stuff is simple.

    Simple solution

    // Simple 'focus' Directive
    import {Directive, Input, ElementRef} from 'angular2/core';
    @Directive({
        selector: '[focus]'
    })
    class FocusDirective {
        @Input()
        focus:boolean;
        constructor(@Inject(ElementRef) private element: ElementRef) {}
        protected ngOnChanges() {
            this.element.nativeElement.focus();
        }
    }
    
    // Usage
    @Component({
        selector : 'app',
        template : `
            <input [focus]="inputFocused" type="text">
            <button (click)="moveFocus()">Move Focus</button>
        `,
        directives: [FocusDirective]
    })
    export class App {
        private inputFocused = false;
        moveFocus() {
            this.inputFocused = true;
            // we need this because nothing will 
            // happens on next method call, 
            // ngOnChanges in directive is only called if value is changed,
            // so we have to reset this value in async way,
            // this is ugly but works
            setTimeout(() => {this.inputFocused = false});
        }
    }
    

    Solution with EventEmitter

    To solve the problem with setTimeout(() => {this.inputFocused = false}); We can bind our directive for events source - EventEmitter, or to Observable. Below is an example of EventEmitter usage.

    // Directive
    import {Directive, EventEmitter, Input, ElementRef} from 'angular2/core';
    
    @Directive({
        selector: '[focus]'
    })
    class FocusDirective {
        private focusEmitterSubscription;   
        // Now we expect EventEmitter as binded value
        @Input('focus')
        set focus(focusEmitter: EventEmitter) {
            if(this.focusEmitterSubscription) {
                this.focusEmitterSubscription.unsubscribe();
            }
            this.focusEmitterSubscription = focusEmitter.subscribe(
                (()=> this.element.nativeElement.focus()).bind(this))
        }    
        constructor(@Inject(ElementRef) private element: ElementRef) {}
    }
    
    // Usage
    @Component({
        selector : 'app',
        template : `
            <input [focus]="inputFocused" type="text">
            <button (click)="moveFocus()">Move Focus</button>
        `,
        directives: [FocusDirective]
    })
    class App {
        private inputFocused = new EventEmitter();
        moveFocus() {
            this.inputFocused.emit(null);    
        }
    }
    

    Both solutions solves your problem, but second has a little better performance and looks nicer.

    0 讨论(0)
提交回复
热议问题