Reputation: 177
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
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
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