Bookmark.vue

This is where the users can see and interact with their bookmarked maps.

import

// Importing Vue components for the NavigationBar and Footer
import NavigationBar from "../reusable-layout/NavigationBar.vue";
import Footer from "../reusable-layout/Footer.vue";
// Importing Axios for making HTTP requests and MarkerClusterer for clustering markers on Google Maps
import axios from "axios";
import { MarkerClusterer } from "@googlemaps/markerclusterer";

Above, we are importing the NavigationBar and Footer component which is a reusable layout because navigation bars and footers are usually same for each page so instead of writing it for each page, it's better to write it in one Vue page and import it in each page as components

Next, is the "axios" package which is used to make API call to the backend (Laravel). It is important because this is like the key that allows us to communicate with the backend.

Finally, is the "MarkerClusterer" package. This package is used to make clusters in the map when there are too many markers in the map. This makes the map less messy and reduces lag.

export default

// Exporting the Vue component
export default {}

Inside this is where we define data, methods, computed properties, and lifecycle hooks.

components

// Register the imported components
components: {
  NavigationBar,
  Footer,
}

The components option is used to register and make Vue external components available for use within this component

data

// Data properties of the component
data() {
  return {
    domainBackend: "",
    domainFrontend: "",
    map: null,
    allData: [],
  };
}

The data method is used to initialize and define the data properties for this component. See the source code to know what each variable is used for.

mounted

// Lifecycle hook: Executed when the component is mounted to the DOM
mounted() {
  // Scroll to the top of the window when the component is mounted
  window.scrollTo(0, 0);
  // Checking if the user is logged in by checking the availability of a cookie
  if (!this.$cookie.isCookieAvailable("L_userId")) {
    alert("LOGIN REQUIRED.");
    // Redirecting to the login page if not logged in
    location.replace(this.domainFrontend + "/login");
  } else {
    // Setting backend domain from the Vuex store
    this.domainBackend = this.$store.state.domainBackend;
    // Fetching and initializing bookmarks when the component is mounted
    this.getBookmark();
  }
}

This is called mounted lifecycle hook. The mounted hook is called after the component has been added to the DOM, making it a good place to perform initial setup and actions.

To explain what this mounted hook does:

  1. It scrolls the window to the top so the user sees the content at the beginning of the page.

  2. If not logged in, then it will alert the user to log in using an account.

  3. If logged in, it gets the backend domain from what is defined in the Vuex and get the JSON representation of the map data array of all the bookmarked maps from the backend.

methods

// Methods of the component
methods: {}

The methods option is used to define methods that can be called or triggered within a Vue component. These methods are typically used to define the behavior and functionality of the component

storeBookmark

// Method to store bookmarks on the backend server
storeBookmark() {
  // Prepare the data to be sent in the request
  const request = {
    jsonData: JSON.stringify({
      USER_ID: this.$cookie.getCookie("L_userId"), // Get the user ID from cookies
      DATA: this.allData, // Include the bookmark data to be stored
    }),
  };
  // Send a POST request to the backend API endpoint for storing bookmarks
  axios
    .post(this.domainBackend + "/api/storeBookmark", request)
    .then((response) => {
      // Upon a successful response from the server
      if (response.data.SUCCESS == 1) {
        // Do nothing or handle success as needed
      }
    });
}

To explain what this storeBookmark method does:

  1. It will send the JSON representation of the map data array along with the user's ID to the backend.

  2. The backend will write the JSON onto the user's bookmark file.

getBookmark

// Method to retrieve bookmarks from the backend server
getBookmark() {
  // Prepare the request object containing the user ID
  const request = {
    userId: this.$cookie.getCookie("L_userId"), // Get the user ID from cookies
  };
  // Send a POST request to the backend API endpoint for retrieving bookmarks
  axios
    .post(this.domainBackend + "/api/getBookmark", request)
    .then((response) => {
      // Upon a successful response from the server
      if (response.data.SUCCESS == 1) {
        // Set the received bookmark data to the component's 'allData' property
        this.allData = response.data.DATA;
        // Check if there are no bookmarks
        if (this.allData.length == 0) {
          // If no bookmarks, initialize the map
          this.initMap();
        } else {
          // If bookmarks exist, add markers to the map based on the data
          this.addMarkers(this.allData);
        }
        // Update the table with the bookmark data
        this.updateTable(this.allData);
      }
    });
}

To explain what this getBookmark method does:

  1. It will send the user's ID to the backend.

  2. The backend will respond with the JSON representation of the map data array of all the bookmarked maps from the backend.

  3. If the map data array is empty, then it will just initialize an empty map to display, and populate the table with rows.

  4. If the map data array is not empty, then it will add the markers in the map, and populate the table with rows.

initMap

// Method to initialize the map
initMap() {
  // Create a new Google Map and assign it to the component's 'map' property
  this.map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 0, lng: 0 }, // Set the initial center of the map to latitude 0, longitude 0
    zoom: 2, // Set the initial zoom level of the map
    markers: [], // Initialize an empty array to store markers on the map
  });
}

To explain what this initMap method does:

  1. It initializes a Google Map on the page.

addMarkers

// Method to add markers to the map based on the provided data
addMarkers(data) {
  // Check if there is data to display
  if (data.length != 0) {
    // Reset the map by setting it to null and initializing a new map
    this.map = null;
    this.initMap();
    // Initialize an array to store markers
    const markers = [];
    // Variable to keep track of the current open info window
    let currentInfoWindow = null;
    // Loop through each data point (place) to add markers to the map
    data.forEach((place) => {
      // Create a new Google Maps Marker for each place
      const marker = new google.maps.Marker({
        position: {
          lat: parseFloat(place.LATITUDE),
          lng: parseFloat(place.LONGITUDE),
        },
        map: this.map, // Set the marker on the map
        title: place.NAME,
      });
      // Add a click event listener to each marker
      marker.addListener("click", () => {
        // Close the current info window if one is open
        if (currentInfoWindow) {
          currentInfoWindow.close();
        }
        // Create a div element for the info window content
        const mainDiv = document.createElement("div");
        // Create div elements for the title, coordinates, and icons
        const titleHolderDiv = document.createElement("div");
        titleHolderDiv.setAttribute("class", "titleHolder");
        titleHolderDiv.innerHTML =
          '<strong style="color:black;">' + place.NAME + "</strong>";
        const coordinateHolderDiv = document.createElement("div");
        coordinateHolderDiv.setAttribute("class", "coordinateHolder");
        coordinateHolderDiv.innerHTML =
          "<p><b>LATITUDE:</b>" +
          place.LATITUDE +
          "</p><p><b>LONGITUDE:</b>" +
          place.LONGITUDE +
          "</p>";
        const iconsHolderDiv = document.createElement("div");
        iconsHolderDiv.setAttribute("class", "iconsHolder");
        // Create buttons for sharing, locating, and editing
        const shareButtonDiv = document.createElement("div");
        shareButtonDiv.setAttribute("class", "icon");
        shareButtonDiv.style.backgroundColor = "white";
        shareButtonDiv.style.borderColor = "white";
        shareButtonDiv.addEventListener("click", () =>
          this.shareRow(place)
        );
        shareButtonDiv.innerHTML =
          '<i class="fas fa-share-nodes" aria-hidden="true"></i><span class="tooltiptext">Share</span>';
        const locationButtonDiv = document.createElement("div");
        locationButtonDiv.setAttribute("class", "icon");
        locationButtonDiv.style.backgroundColor = "white";
        locationButtonDiv.style.borderColor = "white";
        locationButtonDiv.addEventListener("click", () => {
          const url =
            "https://www.google.com/maps/search/?api=1&query=" +
            place.LATITUDE +
            "%2C" +
            place.LONGITUDE;
          window.open(url, "_blank");
        });
        locationButtonDiv.innerHTML =
          '<i class="fas fa-location-dot" aria-hidden="true"></i><span class="tooltiptext">Locate</span>';
        const editButtonDiv = document.createElement("div");
        editButtonDiv.setAttribute("class", "icon");
        editButtonDiv.style.backgroundColor = "white";
        editButtonDiv.style.borderColor = "white";
        editButtonDiv.addEventListener("click", () => this.editRow(place));
        editButtonDiv.innerHTML =
          '<i class="fas fa-edit" aria-hidden="true"></i><span class="tooltiptext">Edit</span>';
        // Append the buttons to the icons holder
        iconsHolderDiv.appendChild(shareButtonDiv);
        iconsHolderDiv.appendChild(locationButtonDiv);
        iconsHolderDiv.appendChild(editButtonDiv);
        // Append the title, coordinates, and icons holders to the main div
        mainDiv.appendChild(titleHolderDiv);
        mainDiv.appendChild(coordinateHolderDiv);
        mainDiv.appendChild(iconsHolderDiv);
        // Create a new Google Maps InfoWindow with the main div as content
        const infowindow = new google.maps.InfoWindow({
          content: mainDiv,
        });
        // Open the info window on the map for the clicked marker
        infowindow.open(this.ETM_map, marker);
        // Update the currentInfoWindow variable
        currentInfoWindow = infowindow;
      });
      // Store the marker in the markers array
      markers.push(marker);
      // Update the map property in the component
      const map = this.map;
      this.map = map;
    });
    // Update the map center and zoom level based on the first data point
    const map = this.map;
    map.setCenter({
      lat: parseFloat(data[0].LATITUDE),
      lng: parseFloat(data[0].LONGITUDE),
    });
    map.setZoom(10);
    // Create a MarkerClusterer to cluster the markers on the map
    const markerCluster = new MarkerClusterer({
      map: map,
    });
    // Add each marker to the marker cluster
    markers.forEach((marker) => {
      markerCluster.addMarker(marker);
    });
    // Set the markers property on the map with the array of markers
    map.markers = markers;
    // Update the map property in the component
    this.map = map;
  } else {
    // If there is no data, reset the map
    this.map = null;
    this.initMap();
  }
}

To explain what this addMarkers method does:

  1. if the map data is not empty, it proceeds with the following steps; otherwise, it initializes the map and sets it to null.

  2. It initializes a Google Map and creates an empty array to hold markers.

  3. It iterates through each item in the map data, creating a marker on the map for each place listed in the map data. Each marker has a title, a click event listener, and an info window that displays additional information about the place when clicked.

  4. It sets up icons and event listeners for buttons within the info window, allowing actions like sharing, locating on Google Maps, editing, and bookmarking the place.

  5. The markers are clustered together for better visualization when there are multiple markers in close proximity.

updateTable

// Method to update the table with data
updateTable(data) {
  // Create a deep copy of the data to avoid modifying the original data
  const duplicate_data = JSON.parse(JSON.stringify(data));
  // Remove the 'WKT' property from each item in the copied data
  duplicate_data.forEach((item) => {
    if (item.hasOwnProperty("WKT")) {
      delete item.WKT;
    }
  });
  // Create a Proxy for the copied data
  const proxy_data = new Proxy(duplicate_data, {
    get: function (target, prop) {
      return target[prop];
    },
    set: function (target, prop, value) {
      target[prop] = value;
      return true;
    },
  });
  // Get references to the table head row and table body in the HTML
  const tableHeadRow = document.getElementById("table-tr");
  const tableBody = document.getElementById("mtsTbody");
  // Clear the existing content of the table head row and table body
  tableHeadRow.innerHTML = "";
  tableBody.innerHTML = "";
  // Check if there is data to display
  if (proxy_data.length != 0) {
    // Create a Set to store all unique property names across the data
    const allProperties = new Set();
    // Iterate through each item in the data to collect unique property names
    proxy_data.forEach((item) => {
      Object.keys(item).forEach((propertyName) => {
        allProperties.add(propertyName);
      });
    });
    // Create table header cells for each unique property name
    allProperties.forEach((propertyName) => {
      const th = document.createElement("th");
      th.textContent = propertyName;
      tableHeadRow.appendChild(th);
    });
    // Add "EDIT" and "OTHER ACTION" columns to the table header
    let th = document.createElement("th");
    th.textContent = "EDIT";
    tableHeadRow.appendChild(th);
    th = document.createElement("th");
    th.textContent = "OTHER ACTION";
    tableHeadRow.appendChild(th);
    // Iterate through each item in the data to populate the table rows
    proxy_data.forEach((item) => {
      const row = document.createElement("tr");
      // Create table cells for each property in the item
      allProperties.forEach((propertyName) => {
        const cell = document.createElement("td");
        cell.style.textAlign = "center";
        const propertyValue = item[propertyName];
        // Display the property value in the table cell
        if (propertyValue !== undefined && propertyValue !== null) {
          cell.textContent = propertyValue;
        } else {
          // Handle the case where the property value is undefined or null
          // Optionally, you can set a background color or add other styling
          // cell.style.backgroundColor = "#adadad";
        }
        // Append the cell to the table row
        row.appendChild(cell);
      });
      // Create an "EDIT" cell with an edit button for each item
      const editCell = document.createElement("td");
      const editButton = document.createElement("button");
      editButton.setAttribute("class", "button");
      editButton.innerHTML = "<i class='fas fa-edit'></i>";
      editButton.addEventListener("click", () => this.editRow(item));
      editCell.appendChild(editButton);
      row.appendChild(editCell);
      // Create an "OTHER ACTION" cell with delete, map, and share buttons
      const otherCell = document.createElement("td");
      const deleteButton = document.createElement("button");
      deleteButton.classList.add("button");
      deleteButton.innerHTML = "<i class='fa fa-trash'></i>";
      deleteButton.addEventListener("click", () => this.deleteRow(item));
      otherCell.appendChild(deleteButton);
      // Create a button to open Google Maps for the item's coordinates
      const markerButton = document.createElement("a");
      markerButton.href =
        "https://www.google.com/maps/search/?api=1&query=" +
        item["LATITUDE"] +
        "%2C" +
        item["LONGITUDE"];
      markerButton.target = "_blank";
      markerButton.innerHTML =
        "<button class='button'><i class='fa fa-map-marker'></i></button>";
      otherCell.appendChild(markerButton);
      // Create a button to share the item's information
      const shareButton = document.createElement("button");
      shareButton.classList.add("button");
      shareButton.innerHTML = "<i class='fa fa-share-nodes'></i>";
      shareButton.addEventListener("click", () => this.shareRow(item));
      otherCell.appendChild(shareButton);
      // Append the "OTHER ACTION" cell to the table row
      row.appendChild(otherCell);
      // Append the table row to the table body
      tableBody.appendChild(row);
    });
  }
}

To explain what this updateTable method does:

  1. It creates a deep copy of the map data using JSON serialization and parsing. This is done to avoid modifying the original data.

  2. It removes the "WKT" property from each object in map data if it exists.

  3. It creates a Proxy object of the map data that allows getting and setting properties while ensuring they are always set successfully.

  4. It selects the table's header row and body elements in the HTML document.

  5. It clears the existing content of the table's header row and body.

  6. If Proxy object is not empty, it proceeds to dynamically generate the table's header based on the properties of the objects in the Proxy object.

  7. It iterates over the properties of the objects to create table header cells and appends them to the header row.

  8. For each object in the Proxy object, it generates a new row in the table body, filling in cells with property values.

  9. It adds buttons to each row in the "EDIT" and "OTHER ACTION" column. Clicking these buttons triggers specific actions, such as editing, deleting, opening the location on Google Maps, or sharing the row.

deleteRow

// Method to delete a row (item) from the data, update the map and table, and store the changes
deleteRow(item) {
  // Iterate through allData to find the index of the item to be deleted
  for (let i = 0; i < this.allData.length; i++) {
    // Check if the ID of the current item matches the ID of the item to be deleted
    if (this.allData[i].ID == item.ID) {
      // Remove the item from the allData array
      this.allData.splice(i, 1);
      // Exit the loop since the item has been found and removed
      break;
    }
  }
  // Check if allData is now empty
  if (this.allData.length == 0) {
    // If allData is empty, initialize the map with default settings
    this.initMap();
  } else {
    // If allData is not empty, update the map with the remaining data
    this.addMarkers(this.allData);
  }
  // Update the table with the modified allData
  this.updateTable(this.allData);
  // Store the updated data (allData) on the backend
  this.storeBookmark();
}

To explain what this deleteRow method does:

  1. It loops through the currently selected map data array to find the item with an ID that matches the ID of the item that is passed in the method.

  2. Once the matching item is found, it removes it from the currently selected map data array.

  3. It then iterates through the map data array and its nested DATA arrays to find and update the item with the same ID as the ID of the currently selected map data with the modified currently selected map data.

  4. If there are no more items left in the currently selected map data, it sets the map to null and initializes a new map.

  5. If there are still items in the currently selected map data, it add the markers in the map, populates the table, and updates the map entries in the selection section.

  6. The map data array and currently selected map data are saved to the cookie.

  7. If the user is logged in, then the JSON representation of the map data array is sent to the backend so that the backend can write the JSON data to the map file of the user.

shareRow

// Method to prepare and display a shareable link for a specific item
shareRow(item) {
  // Get the HTML element with the id "urlLink"
  const urlLink = document.getElementById("urlLink");
  // Create a shareable link using the item's latitude and longitude
  urlLink.value =
    "https://www.google.com/maps/search/?api=1&query=" +
    item["LATITUDE"] +
    "%2C" +
    item["LONGITUDE"];
  // Get the HTML element with the id "containerShareToSocial"
  const containerShareToSocial = document.getElementById(
    "containerShareToSocial"
  );
  // Display the container for sharing options (e.g., social media)
  containerShareToSocial.style.display = "block";
}

To explain what this shareRow method does:

  1. A pop-up box will be shown where the user can copy the Google Maps link of the map item.

editRow

// Method to display and handle the editing of a row (item) in the map and table
editRow(item) {
  // Get the HTML element with the class "editMap"
  const editMap = document.querySelector(".editMap");
  // Toggle the "show" class to display or hide the editing interface
  editMap.classList.toggle("show");
  // Set the title of the editing interface to the name of the item
  document.getElementById("editMap_Title").innerHTML =
    "<strong>" + item["NAME"] + "</strong>";
  // Get the HTML element with the class "editMap_table"
  const editMap_table = document.querySelector(".editMap_table");
  // Clear the content of the editing table
  editMap_table.innerHTML = "";
  // Get the HTML element with the id "labelClassesContainerEdit"
  const labelClassesContainerEdit = document.getElementById(
    "labelClassesContainerEdit"
  );
  // Clear the content of the label classes container
  labelClassesContainerEdit.innerHTML = "";
  // Create a deep copy of the item to avoid modifying the original data directly
  const modifiedItem = JSON.parse(JSON.stringify(item));
  // Get the list of property names in the modifiedItem
  const propertyList = Object.keys(modifiedItem);
  // Iterate through each property of the item
  for (let i = 0; i < propertyList.length; i++) {
    const propertyName = propertyList[i];
    const propertyValue = modifiedItem[propertyName];
    // Create a div element to hold each form element
    const divElement = document.createElement("div");
    divElement.className = "form-group";
    // Create a label element for the property
    const labelElement = document.createElement("label");
    labelElement.className = "form-label";
    labelElement.innerHTML =
      "<div style='padding:5px;display:inline-block'>" +
      propertyName +
      "</div>";
    labelElement.setAttribute("name", propertyName);
    divElement.appendChild(labelElement);
    // Check if the property is one of the restricted properties (ID, NAME, LATITUDE, LONGITUDE)
    if (
      propertyName == "ID" ||
      propertyName == "NAME" ||
      propertyName == "LATITUDE" ||
      propertyName == "LONGITUDE"
    ) {
      // Do nothing for these properties
    } else {
      // For other properties, create a delete button and attach an event listener to remove the form element
      var deleteButton = document.createElement("div");
      deleteButton.setAttribute("class", "buttonFormElementDelete");
      deleteButton.textContent = "DELETE";
      deleteButton.addEventListener("click", () => {
        divElement.remove();
      });
      divElement.appendChild(deleteButton);
    }
    // Create an input element for the property value
    const inputElement = document.createElement("input");
    inputElement.id = propertyName;
    inputElement.type = "text";
    inputElement.className = "form-control";
    inputElement.value = propertyValue;
    // Set readOnly property for certain properties
    if (
      propertyName == "ID" ||
      propertyName == "LATITUDE" ||
      propertyName == "LONGITUDE"
    ) {
      inputElement.readOnly = true;
    } else {
      inputElement.readOnly = false;
    }
    // Append the input element to the div element
    divElement.appendChild(inputElement);
    // Append the div element to the editing table
    editMap_table.appendChild(divElement);
  }
  // Get the HTML element with the id "saveChanges"
  const saveButton = document.getElementById("saveChanges");
  // Add an event listener to the save button to handle changes
  saveButton.addEventListener("click", () => {
    // Get the current state of the editing table
    var editMap_table = document.getElementById("editMap_table");
    var labelList = editMap_table.querySelectorAll("label");
    var item = {};
    // Iterate through each label (property) in the editing table
    for (let i = 0; i < labelList.length; i++) {
      const label = labelList[i];
      const labelText = label.getAttribute("name");
      // Get the value from the corresponding input element
      const inputName = document.getElementById(labelText).value;
      item[labelText] = inputName;
    }
    // Get the label classes container
    var labelClassesContainerEdit = document.getElementById(
      "labelClassesContainerEdit"
    );
    // Iterate through label classes and update the item
    labelList = labelClassesContainerEdit.querySelectorAll("label");
    for (let i = 0; i < labelList.length; i++) {
      const label = labelList[i];
      const labelText = label.getAttribute("name");
      // Get the value from the corresponding input element
      const inputName = document.getElementById(labelText).value;
      item[labelText] = inputName;
    }
    // Create a proxy for the item to intercept and handle property changes
    const proxy_item = new Proxy(item, {
      get: function (target, prop) {
        return target[prop];
      },
      set: function (target, prop, value) {
        target[prop] = value;
        return true;
      },
    });
    // Update the corresponding item in the allData array with the edited item
    for (let i = 0; i < this.allData.length; i++) {
      if (this.allData[i].ID == proxy_item.ID) {
        this.allData[i] = proxy_item;
      }
    }
    // Update the map with the modified data
    this.addMarkers(this.allData);
    // Update the table with the modified data
    this.updateTable(this.allData);
    // Store the changes to the backend
    this.storeBookmark();
  });
}

To explain what this editRow method does:

  1. It toggles the visibility of the pop-up box for editing the row.

  2. It updates the title of the pop-up box to display the name of the map item being edited.

  3. It retrieves the list of property names from map item and iterates through them.

  4. For each property, it creates an input field in the editing interface and populates it with the property's value. It also adds a "DELETE" button for properties other than "ID", "NAME", "LATITUDE", and "LONGITUDE." The "DELETE" button allows removing properties from the item.

  5. When the "Save Changes" button is clicked, it retrieves the updated values of the properties from the input fields.

  6. It uses a Proxy object to allow getting and setting properties in the item.

  7. It updates the corresponding map item in the currently selected map data with the edited map item.

  8. It also updated the map data array with the modified currently selected data.

  9. It add the markers in the map, populates the table, and updates the map entries in the selection section.

  10. The map data array and currently selected map data are saved to the cookie.

  11. If the user is logged in, then the JSON representation of the map data array is sent to the backend so that the backend can write the JSON data to the map file of the user.

addLabelClassToEdit

// Method to add a label class to the editing interface
addLabelClassToEdit() {
  // Prompt the user for a label title
  var labelTitle = prompt("LABEL:");
  // Check if the user entered a non-empty label title
  if (labelTitle !== null && labelTitle.trim() !== "") {
    // Get the container for label classes in the editing interface
    var labelClassesContainerEdit = document.getElementById(
      "labelClassesContainerEdit"
    );
    // Create a container div for the new label class
    var labelClassContainer = document.createElement("div");
    labelClassContainer.classList.add("form-group");
    // Create a label element for the new label class
    var titleLabel = document.createElement("label");
    titleLabel.classList.add("form-label");
    titleLabel.innerHTML =
      "<div style='padding:5px;display:inline-block'>" +
      labelTitle.toUpperCase() +
      "</div>";
    titleLabel.textContent = labelTitle.toUpperCase();
    titleLabel.setAttribute("name", labelTitle.toUpperCase());
    // Create a delete button for removing the label class
    var deleteButton = document.createElement("div");
    deleteButton.setAttribute("class", "buttonFormElementDelete");
    deleteButton.textContent = "DELETE";
    deleteButton.addEventListener("click", () => {
      // Remove the label class container when the delete button is clicked
      labelClassContainer.remove();
    });
    // Create an input element for the value of the label class
    var valueInput = document.createElement("input");
    valueInput.setAttribute("type", "text");
    valueInput.setAttribute("class", "form-control");
    valueInput.setAttribute("id", labelTitle.toUpperCase());
    valueInput.setAttribute("value", "");
    // Append the elements to the label class container
    labelClassContainer.appendChild(titleLabel);
    labelClassContainer.appendChild(deleteButton);
    labelClassContainer.appendChild(valueInput);
    // Append the label class container to the label classes container
    labelClassesContainerEdit.appendChild(labelClassContainer);
  }
}

To explain what this addLabelClassToEdit method does:

  1. It prompts the user for a label title, and it stores the user's.

  2. If the label title is not null and is not just whitespace, it proceeds to create and add an HTML element for this label in the pop-up box for editing the row.

  3. It creates a label element for the title.

  4. It creates an input field for the label's value, setting its initial value to an empty string.

  5. It creates a "DELETE" button for removing the label, which triggers the removal of the label when clicked.

closeEditMap

// Method to close the editing map interface
closeEditMap() {
  // Select the editing map container using its class
  const editMap = document.querySelector(".editMap");
  // Remove the "show" class to hide the editing map interface
  editMap.classList.remove("show");
}

To explain what this closeEditMap method does:

  1. It will the close the pop-up box for editing the row.

Last updated