<ইনপুট> উপাদানটিতে ফোকাস সেট করুন


101

আমি কৌনিক 5 এর সাথে একটি ফ্রন্ট-এন্ড অ্যাপ্লিকেশন কাজ করছি, এবং আমার একটি অনুসন্ধান বাক্স লুকানো থাকা দরকার, তবে একটি বোতামের ক্লিকের উপর, অনুসন্ধান বাক্সটি প্রদর্শিত এবং ফোকাস করা উচিত।

আমি স্ট্যাকওভারফ্লোতে নির্দেশনা বা এর সাথে পাওয়া কয়েকটি উপায় চেষ্টা করেছি, তবে সফল হতে পারি না।

নমুনা কোডটি এখানে:

@Component({
   selector: 'my-app',
   template: `
    <div>
    <h2>Hello</h2>
    </div>
    <button (click) ="showSearch()">Show Search</button>
    <p></p>
    <form>
      <div >
        <input *ngIf="show" #search type="text"  />            
      </div>
    </form>
    `,
  })
  export class App implements AfterViewInit {
  @ViewChild('search') searchElement: ElementRef;

  show: false;
  name:string;
  constructor() {    
  }

  showSearch(){
    this.show = !this.show;    
    this.searchElement.nativeElement.focus();
    alert("focus");
  }

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

অনুসন্ধান বাক্সটি ফোকাস করার জন্য সেট করা নেই।

আমি এটা কিভাবে করবো?

উত্তর:


121

শো অনুসন্ধান পদ্ধতিটি এর মতো পরিবর্তন করুন

showSearch(){
  this.show = !this.show;  
  setTimeout(()=>{ // this will make the execution after the above boolean has changed
    this.searchElement.nativeElement.focus();
  },0);  
}

14
কেন আমাদের সেটটাইমআউট ব্যবহার করা দরকার? বুলিয়ান সিঙ্ক্রোনাসের পরিবর্তন কি নয়?
আন্দ্রেই রোসু

4
জোনজদের সাথে কি এই জগাখিচুড়ি হয় না?
আইনফটোগ

4
@AndreiRosu, এটা ছাড়া আমি একটি ত্রুটি পেয়ে করা হয়েছে কারণ পরিবর্তন অনুষ্ঠিত হয় নি
ইসলাম প্র:

11
এটি কাজ করে, তবে স্পষ্ট ব্যাখ্যা ছাড়াই এটি যাদু। যাদু প্রায়শই বিরতি দেয়।
জন হোয়াইট

4
প্যানেলটি খোলার সময় আমি আমার উপাদানটি একটি প্যানেলে ফোকাস করার চেষ্টা করছিলাম, সুতরাং 0 setTimeout(() => { this.searchElement.nativeElement.focus() }, 100)
টাইমআউটটি

41

এর জন্য আপনার এইচটিএমএল অটোফোকাস ব্যবহার করা উচিত :

<input *ngIf="show" #search type="text" autofocus /> 

দ্রষ্টব্য: যদি আপনার উপাদানটি অবিরত থাকে এবং পুনরায় ব্যবহার করা হয় তবে কেবলমাত্র খণ্ডটি প্রথমবার সংযুক্ত হওয়ার পরে এটি অটোফোকাস করবে। এটি একটি বিশ্বব্যাপী ডোম শ্রোতার দ্বারা অতিক্রম করা যেতে পারে যা কোনও ডোম খণ্ডের সাথে সংযুক্ত থাকে এবং তারপরে এটি পুনরায় প্রয়োগ করে বা জাভাস্ক্রিপ্টের মাধ্যমে ফোকাস করে এমন অটোফোকস বৈশিষ্ট্য পরীক্ষা করে।


42
এটি কেবলমাত্র একাধিক বার নয়, প্রতিটি পৃষ্ঠার রিফ্রেশের জন্য কাজ করবে।
মরিটজগ

22

এই নির্দেশটি তাত্ক্ষণিকভাবে ফোকাস করবে এবং এটি প্রদর্শিত হওয়ার সাথে সাথে উপাদানটির কোনও পাঠ্য নির্বাচন করবে। কিছু ক্ষেত্রে এটির জন্য একটি সেটটাইমআউট প্রয়োজন হতে পারে, এটি খুব বেশি পরীক্ষা করা হয়নি।

import { Directive, ElementRef, OnInit } from '@angular/core';

@Directive({
  selector: '[appPrefixFocusAndSelect]',
})
export class FocusOnShowDirective implements OnInit {

  constructor(private el: ElementRef) {
    if (!el.nativeElement['focus']) {
      throw new Error('Element does not accept focus.');
    }
  }

  ngOnInit(): void {
    const input: HTMLInputElement = this.el.nativeElement as HTMLInputElement;
    input.focus();
    input.select();
  }
}

এবং এইচটিএমএলে:

 <mat-form-field>
     <input matInput type="text" appPrefixFocusAndSelect [value]="'etc'">
 </mat-form-field>

আপনাকে ধন্যবাদ, এটিই একমাত্র সমাধান যা HTTP অনুরোধের জন্য অপেক্ষা করার ক্ষেত্রে আমার পক্ষে কাজ করেছিল
আবদুলহালিম ফেলবাগ শেবার

আমি এই সমাধানটি গৃহীত উত্তরের চেয়ে বেশি পছন্দনীয় বলে মনে করি। কোড পুনরায় ব্যবহারের ক্ষেত্রে এটি আরও পরিস্কার এবং আরও কৌণিক কেন্দ্রিক।
derekbaker783

9

আমি এটি সম্পর্কে বিবেচনা করতে যাচ্ছি (কৌণিক 7 সমাধান)

input [appFocus]="focus"....
import {AfterViewInit, Directive, ElementRef, Input,} from '@angular/core';

@Directive({
  selector: 'input[appFocus]',
})
export class FocusDirective implements AfterViewInit {

  @Input('appFocus')
  private focused: boolean = false;

  constructor(public element: ElementRef<HTMLElement>) {
  }

  ngAfterViewInit(): void {
    // ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
    if (this.focused) {
      setTimeout(() => this.element.nativeElement.focus(), 0);
    }
  }
}


8

এটি সেট টাইমআউট ছাড়াই আইঙ্গুলার 8 এ কাজ করছে:

import {AfterContentChecked, Directive, ElementRef} from '@angular/core';

@Directive({
  selector: 'input[inputAutoFocus]'
})
export class InputFocusDirective implements AfterContentChecked {
  constructor(private element: ElementRef<HTMLInputElement>) {}

  ngAfterContentChecked(): void {
    this.element.nativeElement.focus();
  }
}

ব্যাখ্যা: ঠিক আছে তাই এটি কাজ করে: সনাক্তকরণ পরিবর্তন করুন। এটি একই কারণেই সেটটাইমআউট কাজ করে, তবে কৌনিকটিতে সেটটাইমআউট চালানোর সময় এটি জোন.জেএসকে বাইপাস করে আবার সমস্ত চেক চালায় এবং এটি কাজ করে কারণ যখন সেটটাইমআউট সম্পূর্ণ হয় সমস্ত পরিবর্তন সম্পূর্ণ হয়। সঠিক লাইফাইসাইকেল হুক (আফটার কনটেন্টচেকড) দিয়ে একই ফলাফলটি পৌঁছানো যেতে পারে তবে এই সুবিধাটি নিয়ে যে অতিরিক্ত চক্রটি চালানো হবে না। সমস্ত পরিবর্তনগুলি চেক করা এবং পাস করা হলে ফাংশনটি চালু হবে এবং হুক আফটারকন্টেন্টিট এবং ডোচেকের পরে চলবে। আমি যদি এখানে ভুল হয়ে থাকে তবে দয়া করে আমাকে সংশোধন করুন।

Https://angular.io/guide/lifecycle-hooks এ আরও একটি লাইফসাইকাল এবং সনাক্তকরণের পরিবর্তন

আপডেট : আমি যদি কেউ এংুলার ম্যাটেরিয়াল সিডিকে, এ 11 সি-প্যাকেজ ব্যবহার করে তবে এটি করার আরও একটি ভাল উপায় আমি পেয়েছি। প্রথম আমদানি A11yModule মডিউলে উপাদান প্রকাশক আপনি ইনপুট-ক্ষেত্র আছে তারপর ব্যবহার করুন। CdkTrapFocus এবং cdkTrapFocusAutoCapture HTML এবং ইনপুটের সেট tabIndex মধ্যে নির্দেশনা এবং এই মত ব্যবহার:

<div class="dropdown" cdkTrapFocus cdkTrapFocusAutoCapture>
    <input type="text tabIndex="0">
</div>

পজিশনিং এবং প্রতিক্রিয়াশীলতা সম্পর্কিত আমাদের ড্রপডাউনগুলির সাথে আমাদের কিছু সমস্যা হয়েছিল এবং পরিবর্তে সিডিকে থেকে ওভারলেমডুলি ব্যবহার শুরু হয়েছিল এবং এ 11yModule ব্যবহার করে এই পদ্ধতিটি নির্দোষভাবে কাজ করে।


হাই ... আমি cdkTrapFocusAutoCaptureগুণাবলীর চেষ্টা করি না , তবে আমি আপনার প্রথম উদাহরণটি আমার কোডে পরিবর্তন করেছি। অজানা কারণে (আমার জন্য) এটি আফটারকন্টেন্টচেকড লাইফসাইক্ল হুকের সাথে কাজ করে নি, তবে কেবলমাত্র অননিট দিয়ে। আফটারকন্টেন্টচেকডের সাথে বিশদ বিবরণে আমি ফোকাস পরিবর্তন করতে এবং একই আকারে নির্দেশ ছাড়াই অন্য ইনপুটে (মাউস বা কীবোর্ডের সাহায্যে) সরাতে পারি না।
টিমহেকার

@ টিমহেকার হ্যাঁ, আমাদের উপাদানগুলি সিডিকে ওভারলেতে স্থানান্তরিত করার সময় আমরা একটি অবিচ্ছিন্ন সমস্যার মুখোমুখি হয়েছি (অবস্থানের জন্য ওভারলেটির পরিবর্তে কেবল সিএসএস ব্যবহার করার সময় এটি কাজ করেছিল)। যখন নির্দেশিকা ব্যবহার করে কোনও উপাদান দৃশ্যমান ছিল তখন এটি ইনপুটটিতে অনির্দিষ্টকালের জন্য দৃষ্টি নিবদ্ধ করে। আমি যে সমাধান পেয়েছি তা হ'ল আপডেটে উল্লিখিত সিডিকে নির্দেশিকা ব্যবহার করা।
এসএনডিভিএলএল

6

বুলিয়ান পরিবর্তিত হওয়ার পরে কার্যকর করতে এবং আপনি করতে পারেন এমন টাইমআউট ব্যবহার এড়াতে:

import { ChangeDetectorRef } from '@angular/core';

constructor(private cd: ChangeDetectorRef) {}

showSearch(){
  this.show = !this.show;  
  this.cd.detectChanges();
  this.searchElement.nativeElement.focus();
}

4
আমি কৌণিক 7 দিয়ে এটি চেষ্টা করেছি, এটি কার্যকর হয়নি, সময়সীমা ব্যবহার করে ভাল কাজ করেছে
rekiem87

আমার জন্যও কৌণিক 8 এ কাজ করছে না, খারাপভাবে আমাদের সেটটাইমআউটটিতে ফিরে যেতে হবে
আন্দ্রে

5

কৌনিকটিতে, এইচটিএমএল এর মধ্যেই, আপনি একটি বোতামের ক্লিকের ইনপুটটিতে ফোকাস সেট করতে পারেন।

<button (click)="myInput.focus()">Click Me</button>

<input #myInput></input>

এই উত্তরটি এইচটিএমএল-তে অন্য উপাদানটি প্রোগ্রামগতভাবে নির্বাচন করার একটি সহজ উপায় দেখায়, যা আমি খুঁজছিলাম (সমস্ত "প্রাথমিক ফোকাস" উত্তরগুলি ফোকাস পরিবর্তন করে কোনও ইভেন্টে কীভাবে প্রতিক্রিয়া জানাতে হবে তা সমাধান করে না) - দুর্ভাগ্যক্রমে, আমার প্রতিক্রিয়া দেখাতে হয়েছিল এমন একটি mat-select selectionChangedইভেন্টে যা অন্যান্য ইউআই স্টাফের আগে ঘটে, তাই সেই সময়ে দৃষ্টি নিবদ্ধ করে কাজ করা কার্যকর হয়নি। পরিবর্তে আমি একটি পদ্ধতি লিখতে ছিল setFocus(el:HTMLElement):void { setTimeout(()=>el.focus(),0); }এবং এটি ইভেন্ট হ্যান্ডলার থেকে কল: <mat-select (selectionChanged)="setFocus(myInput)">। হিসাবে সুন্দর না, কিন্তু সহজ এবং ভাল কাজ করে। ধন্যবাদ!
গাস

3

এখানে ডওম বৈশিষ্ট্যও রয়েছে cdkFocusInitialযা ইনপুটগুলিতে আমার পক্ষে কাজ করে। আপনি এটি সম্পর্কে এখানে আরও পড়তে পারেন: https://matory.angular.io/cdk/a11y/overview


"আপনি যদি মেটেরিয়াল ব্যবহার করেন, ...."
অ্যান্ড্রু কোপার



-1

এটি করা সহজ উপায়।

let elementReference = document.querySelector('<your css, #id selector>');
    if (elementReference instanceof HTMLElement) {
        elementReference.focus();
    }

4
আপনি সত্যই ডমকে সরাসরি জিজ্ঞাসা করতে চান না।
রিচার্ড.ড্যাভেনপোর্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.