99

I have such click event

 <button (click)="toggle($event)" class="someclass" id="btn1"></button>
 <button (click)="toggle($event)" class="someclass" id="btn2"></button>

I am catching the event in my function input param and want to find out what exactly button was clicked.

toggle(event) {

}

but event does not have an id property.

altKey: false
bubbles: true
button: 0
buttons: 0
cancelBubble: false
cancelable: true
clientX: 1198
clientY: 29
ctrlKey: false
currentTarget: button#hdrbtn_notificaton.mdl-button.mdl-js-button.mdl-js-ripple-effect.mdl-button--icon
defaultPrevented: false
detail: 1
eventPhase: 3
fromElement: null
isTrusted: true
isTrusted: true
layerX: -566
layerY: 5
metaKey: false
movementX: 0
movementY: 0
offsetX: 22
offsetY: 13
pageX: 1198
pageY: 29
path: Array[13]
relatedTarget: null
returnValue: true
screenX: 1797
screenY: 148
shiftKey: false
sourceCapabilities: InputDeviceCapabilities
srcElement: span.mdl-button__ripple-container
target: span.mdl-button__ripple-container
timeStamp: 1458032708743
toElement: span.mdl-button__ripple-container
type: "click"
view: Window
webkitMovementX: 0
webkitMovementY: 0
which: 1
x: 1198
y: 29

How can I find an id?

UPDATE: Plunkers are all good but in my case I have locally:

event.srcElement.attributes.id - undefined event.currentTarget.id - has the value

I am using chrome latest Version 49.0.2623.87 m

Could it be Material Design Lite thing? because I am using it.

enter image description here

Sergino
  • 10,128
  • 30
  • 98
  • 159

12 Answers12

168

If you want to have access to the id attribute of the button you can leverage the srcElement property of the event:

import {Component} from 'angular2/core';

@Component({
  selector: 'my-app',
  template: `
    <button (click)="onClick($event)" id="test">Click</button>
  `
})
export class AppComponent {
  onClick(event) {
    var target = event.target || event.srcElement || event.currentTarget;
    var idAttr = target.attributes.id;
    var value = idAttr.nodeValue;
  }
}

See this plunkr: https://plnkr.co/edit/QGdou4?p=preview.

See this question:

CcmU
  • 780
  • 9
  • 22
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • 2
    `event.srcElement.attributes.id` is undefined do not know why... but I found an `id` in `event.currentTarget.id` – Sergino Mar 15 '16 at 09:25
  • Really? Did you see my plunkr? It's what I use and it's not undefined... In my case (Chrome), `currentTarget` is undefined :-( Which browser do you use? – Thierry Templier Mar 15 '16 at 09:27
  • In fact, it's either srcElement or target according browsers. See this question: http://stackoverflow.com/questions/5301643/how-can-i-make-event-srcelement-work-in-firefox-and-what-does-it-mean – Thierry Templier Mar 15 '16 at 09:30
  • the Planker is OK but in my particular case I am not getting id locally from `event.srcElement.attributes.id` – Sergino Mar 15 '16 at 09:38
  • `event.target` should work... I updated my answer. What is your particular case? ;-) – Thierry Templier Mar 15 '16 at 09:39
  • I am using `Material Design Lite` may be it is screwing the `event.srcElement.attributes.id` because it is wasn't being build for using with Angular2 for my understanding so may be that is a reason why `event.srcElement.attributes.id` is not working. – Sergino Mar 15 '16 at 09:39
  • 4
    Chrome: `angular2.dev.js:23597 TypeError: Cannot read property 'nodeValue' of undefined` – Sergino Mar 15 '16 at 10:22
  • I think it could be simplified just to this `var target = event.srcElement.attributes.id || event.currentTarget.id;`. The above error I've got in `var value = idAttr.nodeValue;` – Sergino Mar 15 '16 at 10:26
  • The problem is if `event.srcElement` is undefined, you will have an error when trying to access the `attributes` property... – Thierry Templier Mar 15 '16 at 10:29
  • How do you initialize the `idAttr` variable? – Thierry Templier Mar 15 '16 at 10:29
  • 4
    I endup of using this `var target = event.srcElement.attributes.id || event.currentTarget.id;` – Sergino Mar 15 '16 at 10:54
  • @sreginogemoh Try to add id as the second string attribute to onClick function. Works for me! – Skyware Apr 26 '17 at 07:42
  • The expression "event.target || event.srcElement || event.currentTarget" is mixing different things. event.target is the element that fired the event, event.currentTarget is the element on which the listener is registered. In many cases, they are different elements. – Marco Altieri Mar 30 '18 at 14:34
  • @sreginogemoh : Thanks a lot,.. this worked it out.. ng 7.2 – Developer Jan 18 '19 at 14:42
  • depending on your use case, you may want to change the order of: `event.target || event.srcElement || event.currentTarget` – Frazer Kirkman Apr 29 '22 at 18:32
46

For TypeScript users:

    toggle(event: Event): void {
        let elementId: string = (event.target as Element).id;
        // do something with the id... 
    }
quidkid
  • 598
  • 5
  • 5
  • 7
    This should be the accepted answer in my opinion.However it can be ``const elementId: string = (event.target as Element).id;`` – Harish Nov 26 '17 at 05:10
  • 3
    that returns blank for me. Not null or undefined but blank – Darren Street Jun 18 '19 at 09:53
  • Thanks. I was so confused why I couldn't check a property of target, or srcTarget, directly when I could see them all in the console. Cast as Element, duh. – Jeremy L Feb 19 '20 at 21:57
  • This should definitely be the top answer. – NobodySomewhere Oct 27 '20 at 08:23
  • @DarrenStreet how did you solve it? it is blank for me too – Snk Aug 08 '21 at 09:23
  • @Snk Sorry mate, forgotten, 2 years is a long time in coding land. I would have been using a Mat Button so returned a specific mat button event type I recon. Or maybe Viewchild to get a ref to the button. – Darren Street Aug 08 '21 at 09:52
  • @DarrenStreet no prob mate, I'm using primeng so Mat won't work, will try with ViewChild. Thanks! – Snk Aug 08 '21 at 16:05
21

Finally found the simplest way:

<button (click)="toggle($event)" class="someclass" id="btn1"></button>
<button (click)="toggle($event)" class="someclass" id="btn2"></button>

toggle(event) {
   console.log(event.target.id); 
}
ShellZero
  • 4,415
  • 12
  • 38
  • 56
micronyks
  • 54,797
  • 15
  • 112
  • 146
20

You could just pass a static value (or a variable from *ngFor or whatever)

<button (click)="toggle(1)" class="someclass">
<button (click)="toggle(2)" class="someclass">
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
12

There is no need to pass the entire event (unless you need other aspects of the event than you have stated). In fact, it is not recommended. You can pass the element reference with just a little modification.

import {Component} from 'angular2/core';

@Component({
  selector: 'my-app',
  template: `
    <button #btn1 (click)="toggle(btn1)" class="someclass" id="btn1">Button 1</button>
    <button #btn2 (click)="toggle(btn2)" class="someclass" id="btn2">Button 2</button>
  `
})
export class AppComponent {
  buttonValue: string;

  toggle(button) {
    this.buttonValue = button.id;
  }

}

StackBlitz demo

Technically, you don't need to find the button that was clicked, because you have passed the actual element.

Angular guidance

Greg
  • 756
  • 8
  • 16
4

When your HTMLElement doesn't have an id, name or class to call,

then use

<input type="text" (click)="selectedInput($event)">

selectedInput(event: MouseEvent) {
   log(event.srcElement) // HTMInputLElement
}
WasiF
  • 26,101
  • 16
  • 120
  • 128
3

You can use its interface HTMLButtonElement that inherits from its parent HTMLElement !

This way you will be able to have auto-completion...

<button (click)="toggle($event)" class="someclass otherClass" id="btn1"></button>

toggle(event: MouseEvent) {
    const button = event.target as HTMLButtonElement;
    console.log(button.id);
    console.log(button.className);
 }

To see all list of HTMLElement from the World Wide Web Consortium (W3C) documentation

StackBlitz demo

A. Morel
  • 9,210
  • 4
  • 56
  • 45
2

do like this simply: (as said in comment here is with example with two methods)

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app', 
    template: `
      <button (click)="checkEvent($event,'a')" id="abc" class="def">Display Toastr</button>
      <button (click)="checkEvent($event,'b')" id="abc1" class="def1">Display Toastr1</button>
    `
})
export class AppComponent {
  checkEvent(event, id){
    console.log(event, id, event.srcElement.attributes.id);
  }
}

demo: http://plnkr.co/edit/5kJaj9D13srJxmod213r?p=preview

Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215
1

For nested html, use closest

<button (click)="toggle($event)" class="someclass" id="btn1">
    <i class="fa fa-user"></i>
</button>

toggle(event) {
   (event.target.closest('button') as Element).id; 
}
Kurt Van den Branden
  • 11,995
  • 10
  • 76
  • 85
1

You can retrieve the value of an attribute by its name, enabling you to get the value of a custom attribute such as an attribute from a Directive:

<button (click)="toggle($event)" id="btn1" myCustomAttribute="somevalue"></button>


toggle( event: Event ) {
  const eventTarget: Element = event.target as Element;
  const elementId: string = eventTarget.id;
  const attribVal: string = eventTarget.attributes['myCustomAttribute'].nodeValue;
}
StackOverflowUser
  • 945
  • 12
  • 10
0

If you want to have access to the id attribute of the button in angular 6 follow this code

`@Component({
  selector: 'my-app',
  template: `
    <button (click)="clicked($event)" id="myId">Click Me</button>
  `
})
export class AppComponent {
  clicked(event) {
    const target = event.target || event.srcElement || event.currentTarget;
    const idAttr = target.attributes.id;
    const value = idAttr.nodeValue;
  }
}`

your id in the value,

the value of value is myId.

Ehsan
  • 308
  • 6
  • 17
0

You can also use event.path like below

Html:

<tbody>
    <tr *ngFor="let r of rows" id="{{r}}">
        <td>
            <span>
                <button (click)="deleteRow($event)" type="button" 
                class="btn-close"></button> 
            </span>   
        </td>
     </tr>
 </tbody>

ts:

deleteRow(evemt:any){

this.rows.pop()
console.log(evemt.path[3].id);
}

in evemt.path[3].id 3 is which parent's you want to access start from 1 is immediate parent

shyam yadav
  • 214
  • 1
  • 10