Angular : onClick on html element according to its class
Solution 1
Normally the 3rd party widget should provide a click handler like so:
<myWidGet (click)="myFunction($event)"></myWidGet>
and in the controller:
myFunction(evt) {
const target = evt.target
console.log('test')
}
However, if they do not expose click handlers then I would seriously consider not using the widget.
If want to use the widget anyway then do this using jQuery:
ngAfterViewInit() {
$('.dx-edit-row.dx-command-edit.dx-link-save').on('click', (evt) => {
const target = evt.target
console.log('test')
});
}
The above assumes ALL these classes are present on the same button.
Or just use vanilla JS.
If the buttons are not available on ngAfterViewInit()
then you could do this:
ngAfterViewInit() {
const interval = setInterval(() => {
const button = $('.dx-edit-row.dx-command-edit.dx-link-save')
// if button is ready
if (button) {
// add click handlers
button.on('click', (evt) => {
const target = evt.target
console.log('test')
});
// stop polling
clearInterval(interval)
}
}, 100)
}
Solution 2
Accessing DOM elements using jQuery is not really a good practice. Use ElementRef
with Renderer2
instead. Also, there's nothing like ngOnViewInit
in Angular. It's ngAfterViewInit
.
Once the View loads, inside the ngAfterViewInit
, you can get access to the HTMLElement
using the nativeElement
on ElementRef
instance. You should explicitly typecast it into HTMLElement
so as to get intellisence.
You can then call querySelector
on it and pass it the classes. This will give you the button element.
Now you use Renderer2
's instances' listen
method. This takes three args:
- The element you want to listen to events on(
btnElement
). - The Name of the event(
click
). - The callback function.
This would translate to code like:
constructor(
private el: ElementRef,
private renderer: Renderer2
) {}
ngAfterViewInit() {
const btnElement = (<HTMLElement>this.el.nativeElement)
.querySelector('.dx-edit-row.dx-command-edit.dx-link-save');
this.renderer.listen(btnElement, 'click', () => {
alert('Buton was clicked');
});
}
Here's a Working StackBlitz for your ref.
Related videos on Youtube
firasKoubaa
Updated on June 04, 2022Comments
-
firasKoubaa almost 2 years
Under my Angular App, I'm using some 3rd library widget which is rendering in my component.
My template is:
<div> <myWidGet></myWidGet> </div>
Inside
myWidGet
there some button element that I want handle their events. The button have those classes :.dx-edit-row .dx-command-edit .dx-link-save
so i i do that :
export class myClass AfterViewInit { constructor(private elRef: ElementRef){} ngAfterViewInit() { this.elRef.nativeElement.querySelector('.dx-edit-row .dx-command-edit .dx- link-save').on('click', (e) => { alert('test'); }); } }
My purpose is to get reference to my button and handle the click event from it.
Suggestions?
-
Talg123 over 5 yearsI think Im abit confused. why would you use native JS queryselector inside angular? you cant get any interaction with those buttons?
-
miselking over 5 yearsMaybe get
myWidGet
withViewChild
and try getting button withquerySelector
. Although, this way of doing things is not "Angular" way, that button should emit anOutput
event... -
ConnorsFan over 5 yearsYou could set a
click
event handler on thediv
and check the classes of theevent.target
to determine if the widget button was clicked (assuming that theclick
event propagation was not stopped). -
ConnorsFan over 5 yearsSee this stackblitz for an example of event delegation, as suggested in my previous comment.
-
-
firasKoubaa over 5 yearsi ve tried to do it with jquery : the problem that , this button appears after a while (it s a table where i should open some dropdowns to see the button) , so i can t get the console.log working
-
danday74 over 5 yearsok then if the buttons are not available in ngOnViewInit() you will have to poll, i'll add an example to my answer - this code will keep firing until the buttons are ready and then add the click handler and then stop firing, this is not great but this is what happens if you do not use professional 3rd party libs
-
firasKoubaa over 5 yearsi'm using devextereme-angular of DevExpress and for some widget (datagrid) , there is a lack for an edit event
-
danday74 over 5 yearsheres the link for that lib, actually we use it at work and it is a good lib - js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/…
-
danday74 over 5 yearsI've never done editing with it but I believe the data is two way bound, so when you make changes to the datagrid data in the controller the data in the datagrid updates and vice versa, maybe your controller data is updating and thus you do not need to handle the edit event?
-
firasKoubaa over 5 yearswhen you use a datagrid with columns which all refers to cellTemplates , the event "onUpdating" of the datagrid would not detect the changes and will not fire , and there is no way to trigger it ( i need it to send data to WS)
-
danday74 over 5 yearsare the buttons in the cellTemplates? prob not but if so add (click) to the buttons there - if not polling may be the only solution - all the best
-
Christian Vincenzo Traina over 5 years`ElementRef' isn't a so better practice
-
danday74 over 5 yearssorry it is ngAfterViewInit my apologies
-
SiddAjmera over 5 years@CristianTraìna, do you have any mention of that somewhere? I'd like to know more about it. I just feel it's better than polluting your Angular code with jQuery.
-
firasKoubaa over 5 years@SiddAjmera how to do , if my buttonons are not appeared afterViewInit (i would open a dropdown to see the button) ? .. of course without refereing to the click of dropdown opening
-
SiddAjmera over 5 yearsYou mean your buttons are not present in the DOM on View Load?
-
firasKoubaa over 5 yearsthat amazing , but it lack something : my button didn appear onInti of the widegt (it appears after some dropodown opening inside the same widget , how to do it ?
-
firasKoubaa over 5 yearsERROR TypeError: Cannot read property '__zone_symbol__addEventListener' of null
-
Suresh Kumar Ariya over 5 yearsYou can handle this using *ngIf. Set the boolean to true based on ur condition.
-
firasKoubaa over 5 yearsu ven got the ideaa . The button inside the widget is not show since the init of the widget , so that i ve got the last error message . How may i initialize the vent listener when the button appears
-
Suresh Kumar Ariya over 5 yearsi moved those logic to 'AfterViewInit' life cycle hook
-
SiddAjmera over 5 yearsDirectives don't have
AfterViewInit
lifecycle hook. They don't have any hook related to Content or View as they don't have a content or view. -
Christian Vincenzo Traina over 5 years@SiddAjmera you shouldn't just query an element inside a method. Direct access to DOM, in angular, is considered a bad practice. It's better if you just use the default (click) event handler, the angular way