Reputation: 337
In an Angular project I have an SVG map of a country, with all of its regions, and I'm trying to put this SVG map as a template of a component.
So in the SVG file I have each region represented as <path>
or <polygon
element, in total more than 70 regions. And one of the requirements is to highlight each clicked region in a certain color.
Is there a way to handle the click event on each region ( <path>
and <polygon
elements ), other than adding the (click)
event on all of the 70 <path>
and <polygon
elements, because that seems for me a lot code repetition
Note: here I cannot use a loop on the SVG elements.
Upvotes: 0
Views: 1733
Reputation: 8457
Use ViewChild
or ViewChildren
depending on your use-case.
This is a bit pseudo-codeish but it should help you getting started.
@Component({
...
template: `<svg #map>...<svg>`
})
export class MapComponent implements AfterViewInit {
@ViewChild('map') map: HTMLElement // or SvgHTMLElement counterpart
@HostListener('click')
onMapComponentClicked(event: MouseEvent) {
const clickedElement = this.getClickedSvg(event)
if(!clickedElement) return
// Do something with the clicked SVG; maybe read it's ID
}
private getClickedSvg(event: MouseEvent): HTMLElement? {
return (
Array.from(this.map.children).find(el => el.contains(event.target))
)
}
}
Upvotes: 1
Reputation: 2361
I have done it adding a click event on each svg element. Of course you should not do it by yourself but you can navigate programatically in your dom elements and add the click event automatically.
I don't know how your code is but here an exampe:
<svg #mySvg></svg>
in the component.ts maybe something like this should work:
@ViewChild('mySvg') mySvg: SVGElement;
// other code
const children = this.mySvg.children;
for (var i = 0; i < children.length; i++) {
const childElement = children[i];
childElement.addEventListener('click', function (e) {
// Do stuff
});
}
Upvotes: 1