Marek Has
Marek Has

Reputation: 177

Vue.js + SVG Map - how to style selected item?

I have SVG map and .selected class in my which adds color to the selected province:

.selected {
  fill: brown;
}

I cannot add any methods or events to HTML directly, because I will use different maps.

I use an event listener in my methods to access data and render it based on the province that was clicked.

How can I do it with the .selected class? So if I click the given province it get a .selected class and if I click another one the previous one loses the .selected class?

Here is my snippet with my code: https://mdbootstrap.com/snippets/jquery/marektchas/507954

Upvotes: 1

Views: 919

Answers (2)

wwerner
wwerner

Reputation: 4327

You can use a conditional class binding as described in the vue.js docs under Class & Style Bindings

In your case, this could look like

<path d="...snip..."
   id="AL" name="Albania" :class="{selected: province.id == 'AL'}">
</path>

Since this would force you to add the comparison for each province, I'd suggest you render the SVG dynamically:

  • Add the SVG path to the province's data, e.g. { id: 'LT', name: 'Lithuania', vat: 21, path='M707.9 ... 0.5z' }

  • Since you can simply create SVG using vue you can render the provinces in a loop and bind all it's properties, e.g.

      <path v-for="p in provinces" :key="p.id"
          :d="p.path"
          :id="p.id" 
          :name="p.name" 
          :class="{selected: province.id == p.id}">
    

Going this way would significantly shrink your markup.

Upvotes: 1

Sovalina
Sovalina

Reputation: 5609

You can add the .selected class programmatically.

First add a new method to remove the class on all paths, then add the class for the selected element on click:

methods: {

  removeSelection (paths) {
    paths.forEach(el => el.classList.remove("selected")) 
  },

  addClickHandler() {
    let paths = this.$el.querySelectorAll('path')
    paths.forEach(el => {
      let id = el.attributes.id.value
      el.addEventListener('click', () => {
        this.province = this.provinces.find(province => province.id == id)

        this.removeSelection(paths)
        el.classList.add("selected")

        // Animation
        this.isActive = true
        setTimeout(() => { this.isActive = false }, 200)
      })
    })
  }
}

Upvotes: 2

Related Questions