Angular 6: Effectively Triggering the Active Button Among Multiple Buttons Sharing the Same Function Name

I'm facing an issue with a button that toggles the visibility of a password field. I named all the show/hide buttons with the same function, but now when I click on one specific button, it triggers all the textboxes instead of just the current one.

How can I ensure that only the textbox connected to the clicked button is triggered?

HTML

https://i.sstatic.net/Ov17b.png

TS

https://i.sstatic.net/lYRVx.png

Answer №1

Your current issue stems from the shared state of all input fields, which can easily be resolved by assigning individual values to each.

The next question is how to achieve this efficiently. One approach could be to use a simple directive:

import { Directive, HostBinding, Input } from '@angular/core';

@Directive({
  selector: "input[passwordToggler]",
  exportAs: "passwordToggler"
})
export class PasswordToggler {
   @Input("passwordToggler")  
   @HostBinding()
   type: string;

   get visible() { return this.type === "text"; }

   toggleVisibility() {
      if (this.type === "text") {
        this.type = "password";
      } else {
        this.type = "text"; 
      }
   }
}

Once declared in the corresponding module, you can utilize it as follows:

<input passwodToggler="text" #oldInputToggler="passwordToggler"/>
<i [ngClass]="oldInputToggler.visible ? 'bla-text' : 'bla-password'" 
    (click)="oldInputToggler.toggleVisibility()"></i>

Answer №2

To begin with, set

textTypeOld = 'text', textTypeNew = 'text', textTypeRepeat = 'text'

Within the HTML, pass the string to the function changeText like this

changeText("Old") // for old password
changeText("New") // for new password
changeText("Repeat") // for repeat password

In your method,

    changeText(name: string) {
    if(name === "Old") { 
     this.textTypeOld = this.textTypeOld === 'text' ? "password" : "text";
    } else if (name === "New") {  
     this.textTypeNew = this.textTypeNew === 'text' ? "password" : "text";       
    }
    else { 
this.textTypeRepeat = this.textTypeRepeat === 'text' ? "password" : "text";    
    } 
  }

Don't forget to update the type attribute for your input tags and adjust the comparisons in [ngClass] accordingly

Answer №3

In order to retrieve the instance of the element that triggered your event, simply pass $event as an argument in the function call from your HTML.

getTriggeredElement($event)

Then, within your component.ts file, you will have access to the instance of the element for further manipulation or processing.

Answer №4

Let's create a directive that enables toggling between fa-eye and fa-eye-slash classes:

Directive code:

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

@Directive({
  selector: '[appToggleIcon]'
})
export class ToggleIconDirective {

  constructor(private renderer: Renderer2) { }
  private flag = true

  @HostListener('click', ['$event']) onClick($event: Event) {
    this.flag = !this.flag;
    if (this.flag) {
      this.renderer.removeClass($event.target, 'fa-eye');
      this.renderer.addClass($event.target, 'fa-eye-slash')    
    }
    else {
      this.renderer.removeClass($event.target, 'fa-eye-slash');
      this.renderer.addClass($event.target, 'fa-eye');
    }
  }
}

How to use the directive:

<span>
  <i class="fa fa-eye" appToggleIcon>Button3 </i>
</span>
<br>
<span>
  <i class="fa fa-eye" appToggleIcon>Button2 </i>
</span>
<br>
<span>
  <i class="fa fa-eye" appToggleIcon>Button1 </i>
</span>

DEMO: Check how clicking the buttons changes their class.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Are React lifecycle methods failing to execute? Is there a workaround to ensure lifecycle methods are properly triggered?

Today I stumbled upon something unexpected. It's not a common occurrence in Angular or any other JavaScript library or framework. I was surprised when the React lifecycle methods didn't trigger. Is there some kind of hack behind it? Let's ta ...

The attribute 'forEach' is not recognized on the data type 'string | string[]'

I'm experiencing an issue with the following code snippet: @Where( ['owner', 'Manager', 'Email', 'productEmail', 'Region'], (keys: string[], values: unknown) => { const query = {}; ...

Transferring files from one azure blob container to another

I am currently utilizing the @azure/storage-blob package to manage files within Azure. Within the same Azure storage account, I have two storage containers - one for source files and the other for destination files. My objective is to copy a file from th ...

Zone.js error: Promise rejection caught

When I call a function from an external library on page load in my Angular application, Chrome dev tools console shows the error message: "Unhandled Promise rejection: Cannot read properties of undefined (reading 'page') ' Zone: <root> ...

Tips for displaying HTML content dynamically in React using TypeScript after setting a stateVariable

To render an HTML block after successfully setting a state variable, I have defined my state variables and functions below. The code snippet is as follows: const formService = new FormService(); const [appointmentDate, setAppointmentDate] = us ...

What is the TypeScript syntax for defining a component that does not require props to be passed when called?

Can you provide guidance on the correct type to specify for Component in order to compile this example without any type errors? import { memo } from "react"; import * as React from "react"; export function CustomComponent( props: ...

Updating model on button click in Angular 2

When utilizing ngModel in Angular 2 for two-way data binding: <input [(ngModel)]="heroName"> Is there a method to delay updating the model until a button is clicked? Or perhaps have the ability to undo any changes made by the user to the input fiel ...

What made the "in" operator not the best choice in this situation?

When I set out to create a type that represents the values of a given object type, I initially came up with this: type Book = { name:string, year:number, author:string } // expected result "string" | "number" type ValueOf<T ex ...

Guide to integrating a game loop with requestAnimationFrame within various React Redux components

Having trouble brainstorming the optimal approach. One idea is to implement a recursive call with requestAnimationFrame for a game loop: export interface Props { name: string; points: number; onIncrement?: () => void; onDecrement?: () = ...

Construct the output directory according to the specific environment

I'm exploring the process of constructing and launching an Angular 2 project using angular cli with variables specified in my environment typescript files. For instance, within my angular-cli.json file, there is a dev environment linked to "environme ...

Tips for updating the object names when sending a response to an API

After creating the new post, I send this response to the API: "postSummary":"Immediate", "locations":[ { "spSubLocationCode":"CH1", "spSubLocationName":"IGT" ...

Angular jsonp.get request was denied despite receiving a status code of 200 indicating success

I have been attempting to access my basic web API created in Jersey, which returns the following data: [ { "id": 1, "name": "Facebook", "userName": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f4 ...

Issue with unapplied nullable type during export操作

I'm struggling to understand why my nullable type isn't being applied properly Here's an illustration interface Book { name: string; author: string; reference: string; category: string; } async function handleFetch<T>(endpoin ...

Leveraging enums within strictFunctionTypes for Typescript generics

Here is a code snippet (TS playground link): const enum Enum { A, B, C } interface Args { e: Enum.A; } interface GenericClass<A> { new (args: A) : void; } class TestClass { constructor(args: Args) {} } function func<A>(C: GenericCl ...

The compatibility between ng2-file-upload and Angular 6 seems to be causing issues

I am using the ng2-file-upload package with Angular 6 and my backend is in PHP. Although I am able to select a file, when I attempt to upload it, I encounter the following error: Failed to load [api url]: Response to preflight request doesn't pass a ...

Async validator in Angular reactive forms not being triggered

Currently, I'm working with Angular 8 and reactive forms. I have a scenario where I need to validate unique email addresses in an input form control using an async validator. Strangely, the async validator for the email field is not triggering as expe ...

The parent component remains visible in the Angular router

Within my appComponent, I have a layout consisting of a toolbar, footer, and main content. The main content utilizes the router-outlet directive structured as follows: <div class="h-100"> <app-toolbar></app-toolbar> < ...

Testing ng-content in Angular 2

Is there a way to test the functionality of ng-content without the need to create a host element? For instance, let's say we have an alert component - @Component({ selector: 'app-alert', template: ` <div> <ng-conten ...

What are the appropriate Typescript typings for React Components that have the ability to return a string or their child components directly?

What are the suitable types for a React Component that can also output a string or directly its children, in addition to a JSX.Element? For example: type PropsStringExample = Readonly<{ returnString: boolean; }>; type PropsChildrenExample = Readon ...

What is the best way to compare an array of dates with the current date in a React Native application?

I need to evaluate each date from a specific array and check if it matches today's date. If there is a match, I want to set the variable {showImage} to true: data: [ { id: "1", date: "2021-10-05T00:00: ...