redd77
redd77

Reputation: 337

How to control SVG template (click events) in Angular

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

Answers (2)

Some random IT boy
Some random IT boy

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

Zerotwelve
Zerotwelve

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

Related Questions