Passing a value from a prop to a click event that is dynamically created within an SVG Vue.js

Currently, I am in the process of developing a map component using a JSON array and implementing a click event handler for each item. The objective is to toggle the CSS style to color the item when clicked, which is functioning as expected. However, my goal now is to be able to select the color to toggle from a prop. The issue I'm facing is that the value is only set when the function is created, not when it actually fires. I'm seeking guidance on how to access the current value of the 'pickColour' prop within the click event function. Alternatively, how can I determine the equivalent of 'this.node' if an arrow function is used?

Below is the code snippet of my component,

<template>
  <div>
    <div>{{pickColour}}</div>
    <div :id="svgId" class="svg-container"></div>
  </div>
</template>

<script>
import myMap from "../assets/MainMap";
export default {
  name: "VenueMapComponent",
  props: {
    pickColour: String,
  },
  data: function () {
    return {
      svgId: "myMap",
      mapAttr: {
        viewBoxWidth: 1000,
        viewBoxHeight: 2500,
        imageWidth: 1000,
        imageHeight: 2500,
      },
      svgContainer: null,
    };
  },
  mounted: function () {
    this.generateVenueMap();
  },
  methods: {
    generateVenueMap: function () {
      const vue = this;
      const mapData = myMap.g.path;
      const svgContainer = vue
        .$svg("myMap")
        .size("100%", "100%")
        .viewbox(-200, 0, vue.mapAttr.viewBoxWidth, vue.mapAttr.viewBoxHeight);
      vue.svgContainer = svgContainer;
      mapData.forEach((pathObj) => {
        vue.generatePath(svgContainer, pathObj);
      });
    },
    generatePath: function (svgCont, pathObj) {
      const vue = this;
      const attrs = {
        title: pathObj["-title"],
        "map-id": pathObj["-id"],
      };
      const element = svgCont.path(pathObj["-d"]).attr(attrs);

      let mapId = "";
      let title = "";
      element.click(function () {
        mapId = this.node.attributes["map-id"].value;
        title = this.node.attributes["title"].value;

        // need a way to set string from property
        this.node.classList.toggle("def");
        ////

        vue.$emit("map-clicked", { mapId, title });
      });
      element.mouseover(function () {
        mapId = this.node.attributes["map-id"].value;
        title = this.node.attributes["title"].value;
        this.node.classList.add("on");
        //     vue.$emit("map-over", { mapId, title });
      });
      element.mouseout(function () {
        mapId = this.node.attributes["map-id"].value;
        title = this.node.attributes["title"].value;
        this.node.classList.remove("on");
        //     vue.$emit("map-over", { mapId, title });
      });
    },
  },
};
</script>
<style>
path {
  fill: #adaf93;
  stroke: white;
}
path.on {
  fill: rgb(221, 221, 103);
  stroke: rgb(128, 98, 16);
}
path.abc {
  fill: rgb(47, 80, 48);
  stroke: rgb(25, 100, 71);
}
path.abc.on {
  fill: rgb(102, 182, 104);
  stroke: rgb(25, 100, 71);
}
path.def {
  fill: rgb(22, 36, 156);
  stroke: rgb(25, 100, 71);
}
path.def.on {
  fill: rgb(94, 92, 216);
  stroke: rgb(25, 100, 71);
}
</style>

Answer №1

Yes, I managed to figure it out right after my initial post! Using the arrow function was the key solution in this case, so if anybody else is struggling with a similar issue,

element.click(() => {
            mapId = element.node.attributes["map-id"].value;
            title = element.node.attributes["title"].value;

                // finding a way to assign a string from prop value
            element.node.classList.toggle(this.pickColour);
        });
        

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize [markdown links](https://www.markdownguide.org/basic-syntax/#

I have a lengthy text saved in a string and I am looking to swap out certain words in the text with a highlighted version or a markdown link that directs to a glossary page explaining those specific words. The words needing replacement are contained within ...

Insert a new row into a table using tablesorter jQuery

Is it possible to add a row to a table built with the jQuery library "Tablesorter" by simply clicking on a button? I have tried this approach, but unfortunately, the new row does not inherit the CSS properties of Tablesorter. As a result, I am unable to se ...

Trouble arises with Javascript object destructuring when used with this.props in React

Just recently I discovered object destructuring with a basic object, which worked perfectly. However, when attempting to apply it in React on this.props, all my variables are returning as undefined. I'm unsure of what mistake I might be making here. A ...

Struggles with ajax and JavaScript arise when attempting to tally up grades

Currently, I am facing an issue with my JavaScript. The problem arises when trying to calculate marks for each correctly chosen answer based on information from the database. If an incorrect answer is selected, the marks are set to '0', otherwise ...

How can a static website incorporate a local image without the need for backend functionality?

I have a unique challenge with my static website. It is designed to display a local image from the user's computer without utilizing a traditional backend system. The website itself is hosted on a static file server, and all image processing must be d ...

Material-UI - Switching thumb styles in a range slider

Looking for a way to style two entities differently on the Material-UI Slider? Entity A as a white circle and Entity B as a red circle? While using data-index can work, there's a flaw when sliding. Is there a better approach? if (data-index === 0) { ...

Are you experiencing issues with your Ajax request?

I've been struggling to retrieve json data from an API. Despite my efforts, the GET request seems to be executing successfully and returning the correct data when I check the Net tab in Firebug. Can anyone offer advice on what could be going wrong or ...

Should front-end and back-end share Typescript data modeling through classes or interfaces?

I'm currently exploring the best approach to share the same data types between the client (React) and the server (Express + Socket.IO). Within my game, there are various rooms each storing the current status, such as: class GameRoom { players: P ...

Is it possible to reuse a variable within a single HTML tag when using Angular 2?

I encountered a strange issue with Angular 2 that may be a bug. I noticed that I couldn't print the same variable in a template twice within the same HTML tag. When I tried to use the following code, it resulted in error messages. <div class=" ...

Within Vuex, the object store.state.activities contains a specific key labeled "list" which initially holds an array of three items. However, when attempting to access store.state.activities.list directly, an empty array

My project is utilizing Vue. The store.state.activities object contains 2 keys, including an array named list with 3 elements. However, despite attempting to access it using store.state.activities.list, I am getting an empty array. I have experimented w ...

Should we consider packaging the npm dependencies code along with our code as a best practice?

What is the best way to handle npm dependencies in our code bundle? If it's preferable to include the npm dependency code in our bundle, does it make sense to add it as a separate module or package? If not, how can I prevent bundling my dependencie ...

Updating the default value of a MUI TextField: Step-by-step guide

I am in the final stages of completing my form, but I have encountered an issue when trying to display the current user's name in the defaultValue variable of the TextField from MUI. If the value starts as ""/null, or essentially empty, the ...

The initial dropdown menu in PHP coupled with Javascript fails to retain my chosen option

As a novice PHP programmer, I successfully created a double drop-down list from a MySQL database. The idea is to choose a claims hub in the first box and then select an attorney associated with that specific hub in the second box. However, I am facing an ...

Issue: The system does not recognize 'cleancss' as an internal or external command

After successfully installing clean-css via npm command line, I was eager to start using it to concatenate and minify some css files. However, my excitement quickly turned to frustration when I encountered this error: 'cleancss' is not recognize ...

Tips for personalizing the streamlit expander widget

After diving into the streamlit components documentation, it became clear that rendering HTML code for the label parameter of the st.expander() function is not supported. Is there a way to work around this limitation? My exact requirement is as follows: ...

Attempting to utilize the Optimist API's help() function to display the usage() information

I am relatively new to using optimist and despite my attempts at researching and experimenting, I have been unable to find a streamlined method for incorporating a --help option. In the documentation, there is mention of a help() function. Based on this i ...

What is the best way to include multiple action creators in a single listenerMiddleware in Redux Toolkit?

I am looking to store the current state in my database every time there is a change in any of its properties. I have implemented two middlewares to handle this task, each responsible for dispatching the saveTrip function. Although both middlewares are ide ...

Resolving problems with jQuery auto-populating select dropdowns through JSON data

I am facing an issue with auto-populating a select dropdown using jQuery/JSON data retrieved from a ColdFusion CFC. Below is the code snippet: $(function(){ $("#licences-add").dialog({autoOpen:false,modal:true,title:'Add Licences',height:250,wid ...

Header and footer on iPad are not extending to full width even when set to 100% width

Upon viewing this link on an iPad, you may observe that the header does not span the full width of the page, leaving a noticeable pixel gap on the right side. The same issue is present with the footer. It is puzzling to me because both elements are set to ...

Working with npm objects across multiple files

My goal is to integrate the npm package for parallax (lax.js) into my project. The documentation states that in order to initialize it, the following code snippet should be included: window.onload = function () { lax.init() // Add a driver that we use ...