send a websocket message in a route, Express.js

The Goal:

Let’s say we have a marketplace full of shops. I’m creating a specific page localhost:3000/livePurchases/:storeId for a shop owner to monitor live notifications of when they got a new purchase.

enter image description here

enter image description here

alert('you received a new purchase') should be triggered by a WebSocket when an item is purchased.

The Problem:

I need to set up WebSockets on my express server so that the websocket can be triggered somewhere in my code different from where the websocket server was set up. But I don’t understand how to do this.

The websocket should send a message in the route "/newPurchase/:storeId":

app.js

const express = require("express");

module.exports = (config) => {
  const app = express();

  app.post("/newPurchase/:storeId", (req, res, next) => {
    const { storeid } = req.params;
    // trigger websocket message when client requests this route
  });

  return app;
};

But app.js is exported and run from another script, www.js. In real scenarios this is to connect a database before running the app.:

www.js

const app = require("../server/app")();

const port = process.env.PORT || "4000";
app.set("port", port);

app
  .listen(port)
  .on("listening", () =>
    console.log("info", `HTTP server listening on port ${port}`)
  );

module.exports = app;

So that means that the web socket server needs to be set up in www.js.

Below is a notifier service I got it from this tutorial, which seemed like it was trying to solve the problem I have, but it didn’t explain how to implement it. It is a class that handles the websocket.

NotifierService.js

const url = require("url");
const { Server } = require("ws");

class NotifierService {
  constructor() {
    this.connections = new Map();
  }

  connect(server) {
    this.server = new Server({ noServer: true });
    this.interval = setInterval(this.checkAll.bind(this), 10000);
    this.server.on("close", this.close.bind(this));
    this.server.on("connection", this.add.bind(this));
    server.on("upgrade", (request, socket, head) => {
      console.log("ws upgrade");
      const id = url.parse(request.url, true).query.storeId;

      if (id) {
        this.server.handleUpgrade(request, socket, head, (ws) =>
          this.server.emit("connection", id, ws)
        );
      } else {
        socket.destroy();
      }
    });
  }

  add(id, socket) {
    console.log("ws add");
    socket.isAlive = true;
    socket.on("pong", () => (socket.isAlive = true));
    socket.on("close", this.remove.bind(this, id));
    this.connections.set(id, socket);
  }

  send(id, message) {
    console.log("ws sending message");

    const connection = this.connections.get(id);

    connection.send(JSON.stringify(message));
  }

  broadcast(message) {
    console.log("ws broadcast");
    this.connections.forEach((connection) =>
      connection.send(JSON.stringify(message))
    );
  }

  isAlive(id) {
    return !!this.connections.get(id);
  }

  checkAll() {
    this.connections.forEach((connection) => {
      if (!connection.isAlive) {
        return connection.terminate();
      }

      connection.isAlive = false;
      connection.ping("");
    });
  }

  remove(id) {
    this.connections.delete(id);
  }

  close() {
    clearInterval(this.interval);
  }
}

module.exports = NotifierService;

Where I left off implementing the `NotifierService`

I added the websocket server with the NotifierService in www.js

www.js with websockets added

const app = require("../server/app")();
const NotifierService = require("../server/NotifierService.js");
const notifier = new NotifierService();
const http = require("http");
const server = http.createServer(app);
notifier.connect(server);
const port = process.env.PORT || "4000";
app.set("port", port);

server
  .listen(port)
  .on("listening", () =>
    console.log("info", `HTTP server listening on port ${port}`)
  );

module.exports = app;

But now how do I send the websocket message from the /livepPurchases route in app.js? If I create a new instance of NotifierService in app.js order to use the send method in the /livepPurchases route it won’t have access to the connections because it would be a different instance.

Front End:

App.js

import React from "react";

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import LiveStorePurchases from "./LiveStorePurchases";

function App(props) {
  return (
    <div className="App">
      <Router>
        <Switch>
          <Route exact path="/livePurchases/:storeId">
            <LiveStorePurchases />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}

export default App;

LivePurchaseServer.js

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

export default function LiveStorePurchases() {
  let { storeId } = useParams();
  const URL = "ws://127.0.0.1:4000?storeId=" + storeId;

  const [ws, setWs] = useState(new WebSocket(URL));

  useEffect(() => {
    ws.onopen = (e) => {
      newFunction(e);

      function newFunction(e) {
        alert("WebSocket Connected");
      }
    };

    ws.onmessage = (e) => {
      const message = e.data;
      alert(message);
    };

    return () => {
      ws.onclose = () => {
        alert("WebSocket Disconnected");
        setWs(new WebSocket(URL));
      };
    };
  }, [ws.onmessage, ws.onopen, ws.onclose, ws, URL]);

  return (
    <div
      style={{
        color: "red",
        fontSize: "4rem",
      }}
    >
      store: {storeId}
    </div>
  );
}

Javascript set variable value to html color picker hex value

I currently have a project with an html color picker. I also have a variable called color declared using JavaScript. What I’m wondering is how can I set the variable color constantly to the hex value of the color picker. For example, if I change the color picker to blue, the variable color will be set to #009DFF (Hex value for the blue color)

How can this be done? Fiddle containing code: https://jsfiddle.net/AidanYoung/pjw1mzL3/2/

Creating value checker

i want to make a value checker, which would send me my defined response after submitting value.
My requirements:

`If x = 1, x= 2, x=3, then i get response “Not passed”

If x = 4, x=5, x= 6, x= 7, x=8, x=9, x=10 response “passed!”

If x = 4-, x=5+, x=yes response “not a number”

If x= 0, x= 11, x= -2 response “wrong data”

If x is empty (No data entered) response “there are no data!”
`

I am getting stuck when i have to define 4-, 5+,yes as my function is reading those numbers without + and – signs after them and is giving answer “Passed” like for 4 and 5 without + and -, please check it, maybe you get some ideas how to fix it.

For full code: https://codesandbox.io/s/cocky-black-7mezc?file=/ifelse.html:0-2245
My code:

<h2>Ievadi datus</h2>
    <span contenteditable="true" ><p id="ievad"></p></span>
    <button id="poga1">Check!</button>
    <h2>Rezultāts</h2><br>
    <span contenteditable="true" ><p id="izv">Vispirms ievadi datus!</p></span>

And Javascript:

var rezultats = "";
    
    document.getElementById("poga1").onclick = function () 
    {
    
    let izv = document.getElementById("izv");
    let vertejums = document.getElementById("ievad");
    let rezultats = parseFloat(vertejums.textContent);
    return nep(rezultats);
    };
      

    function nep(rezultats){


        if (rezultats <= 0 || rezultats > 10.0){
            izvads = "Wrong data" ;
        }

        else if (rezultats < 4.0){
            izvads = "Not passed!";
        }

        else if (rezultats <= 10.0){
            izvads = "Passed!" ;
        }

        else if (rezultats == "4-", "5+", "yes"){
            izvads = "It's not a number!" ;
        }

        else{
            izvads = "There are no data!" ;
        }

    izv = document.getElementById("izv");
    izv.innerHTML = izvads;
    }

Will be thankful for help!

How do I select other objects in an array that has the same object in javascript and json?

I’m trying to create a code structure where people will list products based on the options they choose, but I got stuck at one point.

I’m pulling the data from the json file but I’m trying to provide the condition as follows. I want to extract the titles, prices and other information from the arrays with the same etiket values and print them to the document.

my Json data:

[
{
    "id": 1,
    "title": "Zincir Tasarımlı El Çantası",
    "price": "49.90",
    "upPrice": "69.90",
    "currency": "&#8378;",
    "images": "./images/yeni.jpg",
    "etiket": {
        "cinsiyet": "kadin",
        "yas": "yas16-20",
        "konsept": "yilbasi"
    }
},
{
    "id": 2,
    "title": "Tüylü Kısa Kol Çanta",
    "price": "74.50",
    "upPrice": "99.90",
    "currency": "&#8378;",
    "images": "./images/yeni1.jpg",
    "etiket": {
        "cinsiyet": "kadin",
        "yas": "yas20-30",
        "konsept": "yilbasi"
    }
},
{
    "id": 3,
    "title": "Zincir Detaylı Kemer Tokalı Çanta",
    "price": "89.90",
    "upPrice": "99.90",
    "currency": "&#8378;",
    "images": "./images/yeni3.jpg",
    "etiket": {
        "cinsiyet": "erkek",
        "yas": "yas16-20",
        "konsept": "yilbasi"
    }
},
{
    "id": 4,
    "title": "Zincirli Uzun Kol Deri Çanta",
    "price": "69.90",
    "upPrice": "89.90",
    "currency": "&#8378;",
    "images": "./images/yeni4.jpg",
    "etiket": {
        "cinsiyet": "erkek",
        "yas": "yas20-30",
        "konsept": "yilbasi"
    }
},
{
    "id": 5,
    "title": "Zincir Tasarımlı El Çantası",
    "price": "49.90",
    "upPrice": "69.90",
    "currency": "&#8378;",
    "images": "./images/yeni5.jpg",
    "etiket": {
        "cinsiyet": "erkek",
        "yas": "yas30-40",
        "konsept": "yilbasi"
    }
},
{
    "id": 6,
    "title": "Zincirli Deri Desenli Çanta",
    "price": "109.90",
    "upPrice": "129.90",
    "currency": "&#8378;",
    "images": "./images/yeni6.jpg",
    "etiket": {
        "cinsiyet": "erkek",
        "yas": "yas45ustu",
        "konsept": "yilbasi"
    }
},
{
    "id": 7,
    "title": "Kısa Kollu Deri Çanta",
    "price": "199.90",
    "upPrice": "269.90",
    "currency": "&#8378;",
    "images": "./images/yeni7.jpg",
    "etiket": {
        "cinsiyet": "kadin",
        "yas": "yas30-45",
        "konsept": "yilbasi"
    }
},
{
    "id": 8,
    "title": "Kahverengi Deri Desenli Kısa Kol Çanta",
    "price": "349.90",
    "upPrice": "369.90",
    "currency": "&#8378;",
    "images": "./images/yeni8.jpg",
    "etiket": {
        "cinsiyet": "kadin",
        "yas": "yas45ustu",
        "konsept": "yilbasi"
    }
}]

I’m giving an example. I want to draw the titles of the same “yilbasi” values, “yas16-20” values and “kadin” values to the page with innerHTML.

But I don’t know how to pull the data of the ones with the same values. I have not been able to create its structure. I want to do it with pure javascript if possible.

How to create accordions so only 1 stays open at a time?

I am having some difficulty using using an accordion in HTML & JS. I am trying to code it so only one accordion is open at a time. If someone clicks and opens a new accordion, all the other should close. This my HTML.

 <div class="accordion">
        <div class="accordion-item">
          <div class="accordion-item-header">
            HUMBER RADIO
          </div>
          <div class="accordion-item-body">
            <div class="accordion-item-body-content">
                <ul>
                    <li><a href="">RADIO NEWS</a></li>
                    <li><a href="">PODCAST</a></li>                 
                    <li><a href="">CONTENT</a></li>                
                </ul>
            </div>
          </div>
        </div>
        </div>
    
        <div class="accordion">
            <div class="accordion-item">
              <div class="accordion-item-header">
                TV NEWS
              </div>
              <div class="accordion-item-body">
                <div class="accordion-item-body-content">
                    <ul>
                        <li><a href="">COVID UPDATES</a></li>
                        <li><a href="">NORTH CAMPUS NEWS</a></li>                 
                        <li><a href="">LAKESHORE CAMPUS NEWS</a></li>                
                    </ul>
                </div>
              </div>
            </div>
            </div>

Here is the JavaScript for the code. It can open all of them, but I am struggling to program it so the others close.

window.onload = pageReady;

function pageReady() {

    const accordionItemHeaders = document.querySelectorAll(".accordion-item-header");

    accordionItemHeaders.forEach(accordionItemHeader => {
      accordionItemHeader.addEventListener("click", event => {
    
        accordionItemHeader.classList.toggle("active");
        const accordionItemBody = accordionItemHeader.nextElementSibling;
        if(accordionItemHeader.classList.contains("active")) {
          accordionItemBody.style.maxHeight = "100px";
        }
        else {
          accordionItemBody.style.maxHeight = "0px";
        }
        
      });
    });
}

I have two JQuery Ajax API calls to a REST API, one doesn’t work why?

I’m doing a get REST api request to a server. The server houses automation jobs what I’m looking to kick off with parameters.

var jobURL = "https://hostname/api/v1/tasks"; 

$.ajax({
    url: jobURL,
    method: 'GET',
    async: false,
    contentType: "application/json",
    data: {
        name: '*JOBNAME*'
    },
    headers: {
        'Authorization': 'Bearer '+ obj.access_token,
        'Content-type': 'application/x-www-form-urlencoded',
        Accept:'application/json'
    },
    success: function(data){
        taskname_obj = data    // result
}

I’m doing this per the documentation of the server product and it is working.

https://docs.ipswitch.com/MOVEit/Automation2021/API/REST-API/index.html#_gettaskusingget

I have a successful request, with items returned in the ‘taskname_obj’ variable.
With that said I’m trying to use the same sort of code for another call.

// THIS IS WORKING TO JOB WITHOUT PARAMS.

        // Let's run the job. 
        $.ajax({
            url: jobURL,
            method: 'POST',
            async: false,
            headers: {
                'Authorization': 'Bearer '+ obj.access_token
            },
            success: function(data){
                taskname_obj2 = data    // result
            }
        })

SO I’m doing the above code to work with the endpoint in the link below:

https://docs.ipswitch.com/MOVEit/Automation2021/API/REST-API/index.html#_starttaskusingpost

Again I am success, I can start my job. I have indication of success returned into taskname_obj2.

With all that said, I am trying to start this with parameters. I suppose I have to put that into the “data:” item, and I shout use JSON. So… I do the following…

var payload = { 
    USER_ID: "",
    BEGDATE: "060121",
    ENDDATE: "121521"
};

$.ajax({
    url: jobURL,
    method: 'POST',
    async: false,
    contentType: 'application/json',
    data: payload,
    headers: {
        'Authorization': 'Bearer '+ obj.access_token,
        'Content-type': 'application/x-www-form-urlencoded',
        Accept:'application/json'
    },
    success: function(data){
        taskname_obj2 = data    // result
    }
})

This doesn’t work. I am getting a 415 error back from the server for unsupported media type. I also tried not using JSON.stringify for the data item but I also get a 415 with that.

I think I’m not telling it correctly how to read my JSON. Can anybody help me understand what I’m doing wrong?

I also tried adding this contentType: 'application/json', to no avail.

how to removechild element from list in JavaScript

when I add a element from right to left I can see element in both view by name and view by code

when I perform delete how to remove value from both the list and disable false for both lists

<form name="adminForm" id="formAdmin" method="post" action="http://localhost:7003/ccrSrc/initAdmin.do">
<table style="margin-top: -15px" cellspacing="0" cellpadding="0" border="0" width="760">
   <tbody>
      <tr bgcolor="#EEEEEE">
         <td width="800" valign="top" style="margin:0px; padding: 0px;">
            <table class="orgtable">
               <tbody>
                  <tr>
                     <td class="tabletitle2" width="40%" nowrap="">Available Orgs:</td>
                     <td class="tabletitle2" width="20%">&nbsp;</td>
                     <td class="tabletitle2" width="40%" nowrap="">Assigned Orgs:</td>
                  </tr>
                  <tr>
                     <!--Available Organizations-->
                     <td width="40%" class="bodytext6">
                        <div class="container">
                           <label class="section-label">Status:</label>
                           <input class="radioBtn" type="radio" name="status" value="ACTIVE" checked="" onclick="javascript:changeStatus(1);">
                           <label class="section-label">Active</label>
                           <input class="radioBtn" type="radio" name="status" value="INACTIVE" onclick="javascript:changeStatus(2);">
                           <label class="section-label">Inactive</label>
                           <br/>
                           <label class="section-label">View:</label>
                           <input class="radioBtn" type="radio" name="viewGrp" value="BYNAME" checked="" onclick="javascript:changeView('BYNAME');">
                           <label class="section-label">    Org Name</label>
                           <input class="radioBtn" type="radio" name="viewGrp" value="BYCODE" onclick="javascript:changeView('BYCODE');">
                           <label class="section-label">Org Code</label>
                        </div>
                        <div id="Status1" style="cursor:default; display: inline;">
                           <select id="" name="activeChnl" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%">
                              <option value="1">Accountancy, Banking and Finance</option>
                              <option value="2">Animal and Plant Resource</option>
                              <option value="3">Business, Consulting and Management</option>
                              <option value="4">Charity and Voluntary Work</option>
                              <option value="5">Creative Arts and Design</option>
                              <option value="6">Energy and Utilities</option>
                              <option value="7">Engineering and Manufacturing</option>
                              <option value="8">Enviromemt amd Agriculture</option>
                              <option value="9">Healthcare</option>
                              <option value="10">Hospitality and Events Management</option>
                           </select>
                        </div>
                        <div id="Status2" style="cursor:default; display: none;">
                           <select name="inactiveChnl" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%">
                              <option value="11">Information, Research and Analysis</option>
                              <option value="12">Insurance and Pensions</option>
                              <option value="13">Law</option>
                              <option value="14">Law Enforcement and Security</option>
                              <option value="15">Leisure, Sport and Tourism</option>
                              <option value="16">Marketing, Advertising and PR</option>
                              <option value="17">Media and Internet</option>
                              <option value="18">Performing Arts</option>
                              <option value="19">Property and Construction</option>
                              <option value="20">Public Services and Administration</option>
                           </select>
                        </div>
                        <div id="Status3" style="cursor:default; display: none;">
                           <select name="activeChnlByCode" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%">
                              <option value="1">001 Accountancy, Banking and Finance</option>
                              <option value="2">002 Animal and Plant Resource</option>
                              <option value="3">003 Business, Consulting and Management</option>
                              <option value="4">004 Charity and Voluntary Work</option>
                              <option value="5">005 Creative Arts and Design</option>
                              <option value="6">006 Energy and Utilities</option>
                              <option value="7">007 Engineering and Manufacturing</option>
                              <option value="8">008 Enviromemt amd Agriculture</option>
                              <option value="9">009 Healthcare</option>
                              <option value="10">010 Hospitality and Events Management</option>
                           </select>
                        </div>
                        <div id="Status4" style="cursor:default; display: none;">
                           <select name="inactiveChnlByCode" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%">
                              <option value="11">011 Information, Research and Analysis</option>
                              <option value="12">012 Insurance and Pensions</option>
                              <option value="13">013 Law</option>
                              <option value="14">014 Law Enforcement and Security</option>
                              <option value="15">015 Leisure, Sport and Tourism</option>
                              <option value="16">016 Marketing, Advertising and PR</option>
                              <option value="17">017 Media and Internet</option>
                              <option value="18">018 Performing Arts</option>
                              <option value="19">019 Property and Construction</option>
                              <option value="20">020 Public Services and Administration</option>
                           </select>
                        </div>
                     </td>
                     <td width="4%" align="center" nowrap="">
                        <button class="addRemoveBtn" name="btnAdd" type="button">&gt;&gt;</button>
                        <br><br><br>
                        <button class="addRemoveBtn" name="btnRemove" type="button">&lt;&lt;</button>
                     </td>
                     <td width="48%" class="smalltext0">
                        <div id="activeStatus1" style="cursor: default; display: inline;">
                           <select name="assignedActiveChnl" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%;height:347px;">
                           </select>
                        </div>
                        <div id="activeStatus2" style="cursor: default; display: none;">
                           <select name="assignedInactiveChnl" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%;height:347px;">
                           </select>
                        </div>
                        <div id="activeStatus3" style="cursor:default; display: none;">
                           <select name="assignedActiveChnlByCode" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%;height:347px;">
                           </select>
                        </div>
                        <div id="activeStatus4" style="cursor:default; display: none;">
                           <select name="assignedInactiveChnlByCode" multiple="multiple" size="25%" style="overflow-x:scroll;width:100%;height:347px;">
                           </select>
                        </div>
                     </td>
                  </tr>
                  <tr>
                     <td></td>
                     <td>
                     </td>
                     <td align="right">
                        <button id="cancel" style="width:75px;" type="button" onclick="javascript:loadUserOrgAction();">Cancel</button>
                        <button id="save" style="width:75px;" type="button" onclick="javascript:loadUserOrgAction();">Save</button>
                     </td>
                  </tr>
               </tbody>
            </table>
         </td>
      </tr>
   </tbody>
</table>
</form> 

below is the JavaScript function for add and remove
when add click is performed i can add value to both assigned list as code and name same behaviour should be work for when i click on remove how can i achieve these ?

var tempAddedActiveOrgs = [];
var tempAddedInactiveOrgs = [];
var tempAddedActiveOrgsByCode = [];
var tempAddedInactiveOrgsByCode = [];

let View1 = true;
let View2 = false;
let Status1 = true;
let Status2 = false;
let ActiveStatus1 = true;
let ActiveStatus2 = false;

function changeStatus(statusId) {
    var frm = document.getElementById('formAdmin');
    var activChnls = frm.activeChnl;
    var inactivChnls = frm.inactiveChnl;
    var sectionName = "Status" + statusId;
    //reset sections
    view1 = false;
    document.getElementById("Status1").style.display = 'none';
    view2 = false;
    document.getElementById("Status2").style.display = 'none';
    //display appropriate section
    if (sectionName == "Status1") {
        Status1 = true;
        document.getElementById("Status1").style.display = 'inline';
        if (activChnls.length < 1) {
            alert('You currently have no Partners assigned. To update your list of assigned Partners, please visit go/updatemyccr and submit a request form.');
            disableButtons();
        } else if (document.getElementById('formAdmin').viewGrp.value == 'BYNAME') {
            document.getElementById("Status1").style.display = 'inline';
            document.getElementById("Status2").style.display = 'none';
            document.getElementById("Status3").style.display = 'none';
            document.getElementById("Status4").style.display = 'none';
            document.getElementById("activeStatus1").style.display = 'inline';
            document.getElementById("activeStatus2").style.display = 'none';
            document.getElementById("activeStatus3").style.display = 'none';
            document.getElementById("activeStatus4").style.display = 'none';
        } else if (document.getElementById('formAdmin').viewGrp.value == 'BYCODE') {
            document.getElementById("Status1").style.display = 'none';
            document.getElementById("Status2").style.display = 'none';
            document.getElementById("Status3").style.display = 'inline';
            document.getElementById("Status4").style.display = 'none';
            document.getElementById("activeStatus1").style.display = 'none';
            document.getElementById("activeStatus2").style.display = 'none';
            document.getElementById("activeStatus3").style.display = 'inline';
            document.getElementById("activeStatus4").style.display = 'none';
        } else {
            enableButtons();
            activChnls.selectedIndex = "0";
            activChnls.focus();
            clearSearch();
        }
    } else if (sectionName == "Status2") {
        Status2 = true;
        document.getElementById("Status2").style.display = 'inline';
        if (inactivChnls.length < 1) {
            disableButtons();
        } else if (document.getElementById('formAdmin').viewGrp.value == 'BYNAME') {
            document.getElementById("Status1").style.display = 'none';
            document.getElementById("Status2").style.display = 'inline';
            document.getElementById("Status3").style.display = 'none';
            document.getElementById("Status4").style.display = 'none';
            document.getElementById("activeStatus1").style.display = 'none';
            document.getElementById("activeStatus2").style.display = 'inline';
            document.getElementById("activeStatus3").style.display = 'none';
            document.getElementById("activeStatus4").style.display = 'none';
        } else if (document.getElementById('formAdmin').viewGrp.value == 'BYCODE') {
            document.getElementById("Status1").style.display = 'none';
            document.getElementById("Status2").style.display = 'none';
            document.getElementById("Status3").style.display = 'none';
            document.getElementById("Status4").style.display = 'inline';
            document.getElementById("activeStatus1").style.display = 'none';
            document.getElementById("activeStatus2").style.display = 'none';
            document.getElementById("activeStatus3").style.display = 'none';
            document.getElementById("activeStatus4").style.display = 'inline';
        } else {
            enableButtons();
            inactivChnls.selectedIndex = "0";
            inactivChnls.focus();
            clearSearch();
        }
    } else {

        Status1 = true;
        document.getElementById("Status1").style.display = 'inline';
        statusId = "1";
    }
}

function changeView(type) {
    if (type == "BYNAME" && document.getElementById('formAdmin').status.value == 'ACTIVE') {
        document.getElementById("Status1").style.display = 'inline';
        document.getElementById("Status2").style.display = 'none';
        document.getElementById("Status3").style.display = 'none';
        document.getElementById("Status4").style.display = 'none';
        document.getElementById("activeStatus1").style.display = 'inline';
        document.getElementById("activeStatus2").style.display = 'none';
        document.getElementById("activeStatus3").style.display = 'none';
        document.getElementById("activeStatus4").style.display = 'none';
    } else if (type == "BYNAME" && document.getElementById('formAdmin').status.value == 'INACTIVE') {
        document.getElementById("Status1").style.display = 'none';
        document.getElementById("Status2").style.display = 'inline';
        document.getElementById("Status3").style.display = 'none';
        document.getElementById("Status4").style.display = 'none';
        document.getElementById("activeStatus1").style.display = 'none';
        document.getElementById("activeStatus2").style.display = 'inline';
        document.getElementById("activeStatus3").style.display = 'none';
        document.getElementById("activeStatus4").style.display = 'none';

    } else if (type == "BYCODE" && document.getElementById('formAdmin').status.value == 'ACTIVE') {
        document.getElementById("Status1").style.display = 'none';
        document.getElementById("Status2").style.display = 'none';
        document.getElementById("Status3").style.display = 'inline';
        document.getElementById("Status4").style.display = 'none';
        document.getElementById("activeStatus1").style.display = 'none';
        document.getElementById("activeStatus2").style.display = 'none';
        document.getElementById("activeStatus3").style.display = 'inline';
        document.getElementById("activeStatus4").style.display = 'none';

    } else if (type == "BYCODE" && document.getElementById('formAdmin').status.value == 'INACTIVE') {
        document.getElementById("Status1").style.display = 'none';
        document.getElementById("Status2").style.display = 'none';
        document.getElementById("Status3").style.display = 'none';
        document.getElementById("Status4").style.display = 'inline';
        document.getElementById("activeStatus1").style.display = 'none';
        document.getElementById("activeStatus2").style.display = 'none';
        document.getElementById("activeStatus3").style.display = 'none';
        document.getElementById("activeStatus4").style.display = 'inline';

    }
}

adminForm.btnAdd.onclick = () => {
    if (document.getElementById("Status1").style.display == 'inline') {
        addActiveChnlOrgs();
    } else if (document.getElementById("Status2").style.display == 'inline') {
        addInactiveChnlOrgs();
    }
}

function addActiveChnlOrgs() {
    var frm = document.getElementById('formAdmin');
    var assignedActiveChnls = frm.assignedActiveChnl;
    var activeChnls = frm.activeChnl;
    var activeChnlByCode = frm.activeChnlByCode;
    var assignedActiveChnlByCode = frm.assignedActiveChnlByCode;
    //adding active selected chnl org by name to assigned chnl org by name 
    for (i = 0; i < activeChnls.length; i++) {
        if (activeChnls[i].selected == true) {
            var opt = document.createElement('option');
            opt.value = activeChnls[i].value;
            opt.innerHTML = activeChnls[i].label;
            assignedActiveChnls.appendChild(opt);
            if (tempAddedActiveOrgs.indexOf(opt.value) === -1) {
                tempAddedActiveOrgs.push(opt.value);
            }
            activeChnls[i].disabled = true;
        }
    }

    //adding active selected chnl org by name to assigned chnl org by code 
    for (i = 0; i < activeChnls.length; i++) {
        if (activeChnls[i].selected == true) {
            for (j = 0; j < activeChnlByCode.length; j++) {
                if (activeChnls[i].value == activeChnlByCode[j].value) {
                    var opt = document.createElement('option');
                    opt.value = activeChnlByCode[j].value;
                    opt.innerHTML = activeChnlByCode[j].label;
                    assignedActiveChnlByCode.appendChild(opt);
                    if (tempAddedActiveOrgsByCode.indexOf(opt.value) === -1) {
                        tempAddedActiveOrgsByCode.push(opt.value);
                    }
                    activeChnlByCode[j].disabled = true;
                }
            }
        }
    }
    activeChnls.selectedIndex = -1;
    activeChnlByCode.selectedIndex = -1;

    sortSelect(assignedActiveChnls);
    sortSelect(assignedActiveChnlByCode);
    extractLabelForDisplay(assignedActiveChnls);
    //color added orgs to blue
    for (var i = 0; i < assignedActiveChnls.length; i++) {
        for (var j = 0; j < tempAddedActiveOrgs.length; j++) {
            if (assignedActiveChnls[i].value == tempAddedActiveOrgs[j]) {
                assignedActiveChnls[i].style.color = "blue";
            }
        }
    }

    for (var i = 0; i < assignedActiveChnlByCode.length; i++) {
        for (var j = 0; j < tempAddedActiveOrgsByCode.length; j++) {
            if (assignedActiveChnlByCode[i].value == tempAddedActiveOrgsByCode[j]) {
                assignedActiveChnlByCode[i].style.color = "blue";
            }
        }
    }
}

function addActiveChnlOrgsByCode() {
    var frm = document.getElementById('formAdmin');
    var assignedActiveChnlByCode = frm.assignedActiveChnlByCode;
    var activeChnlByCode = frm.activeChnlByCode;
    var assignedActiveChnls = frm.assignedActiveChnl;
    var activeChnls = frm.activeChnl;
    //adding active selected chnl org by code to assigned chnl org by code 
    for (i = 0; i < activeChnlByCode.length; i++) {
        if (activeChnlByCode[i].selected == true) {
            var opt = document.createElement('option');
            opt.value = activeChnlByCode[i].value;
            opt.innerHTML = activeChnlByCode[i].label;
            assignedActiveChnlByCode.appendChild(opt);
            if (tempAddedActiveOrgsByCode.indexOf(opt.value) === -1) {
                tempAddedActiveOrgsByCode.push(opt.value);
            }
            activeChnlByCode[i].disabled = true;
        }
    }
    //adding active selected chnl org by code to assigned chnl org by name
    for (i = 0; i < activeChnlByCode.length; i++) {
        if (activeChnlByCode[i].selected == true) {
            for (j = 0; j < activeChnls.length; j++) {
                if (activeChnlByCode[i].value == activeChnls[j].value) {
                    var opt = document.createElement('option');
                    opt.value = activeChnls[j].value;
                    opt.innerHTML = activeChnls[j].label;
                    assignedActiveChnls.appendChild(opt);
                    if (tempAddedActiveOrgs.indexOf(opt.value) === -1) {
                        tempAddedActiveOrgs.push(opt.value);
                    }
                    activeChnls[j].disabled = true;
                }
            }
        }
    }
    activeChnlByCode.selectedIndex = -1;
    activeChnls.selectedIndex = -1;

    sortSelect(assignedActiveChnls);
    sortSelect(assignedActiveChnlByCode);
    extractLabelForDisplay(assignedActiveChnls);
    //color added orgs to blue
    for (var i = 0; i < assignedActiveChnlByCode.length; i++) {
        for (var j = 0; j < tempAddedActiveOrgsByCode.length; j++) {
            if (assignedActiveChnlByCode[i].value == tempAddedActiveOrgsByCode[j]) {
                assignedActiveChnlByCode[i].style.color = "blue";
            }
        }
    }

    for (var i = 0; i < assignedActiveChnls.length; i++) {
        for (var j = 0; j < tempAddedActiveOrgs.length; j++) {
            if (assignedActiveChnls[i].value == tempAddedActiveOrgs[j]) {
                assignedActiveChnls[i].style.color = "blue";
            }
        }
    }
}

adminForm.btnRemove.onclick = () => {
    let frm = document.getElementById('formAdmin')
    let activeAssignedChnl = frm.assignedActiveChnl;
    let inActiveAssignedChnl = frm.assignedInactiveChnl;
    let activeAssignedChnlByCode = frm.assignedActiveChnlByCode;
    let assignedInactiveChnlByCode = frm.assignedInactiveChnlByCode;

    if (document.getElementById("Status1").style.display == 'inline') {
        if (activeAssignedChnlByCode.children.length > 0) {
            let activeChnlByCode = frm.activeChnlByCode;
            for (j = 0; j < activeAssignedChnlByCode.length; j++) {
                if (activeChnlByCode[j].value == activeAssignedChnl.value) {
                    activeChnlByCode[j].disabled = false
                }
            }
        }
        if (activeAssignedChnl.children.length > 0) {
            let activChnls = frm.activeChnl;
            for (i = 0; i < activChnls.length; i++) {
                if (activChnls[i].value == activeAssignedChnl.value) {
                    activChnls[i].disabled = false
                    activeAssignedChnl.removeChild(
                        activeAssignedChnl.options[activeAssignedChnl.selectedIndex]
                    )
                }
            }
        }
    } else if (document.getElementById("Status2").style.display == 'inline') {
        if (inActiveAssignedChnl.children.length > 0) {
            let inactivChnls = frm.inactiveChnl;
            for (i = 0; i < inactivChnls.length; i++) {
                if (inactivChnls[i].value == inActiveAssignedChnl.value) {
                    inactivChnls[i].disabled = false
                    inActiveAssignedChnl.removeChild(
                        inActiveAssignedChnl.options[inActiveAssignedChnl.selectedIndex]
                    )
                }
            }
        }
    } else if (document.getElementById("Status3").style.display == 'inline') {
        if (activeAssignedChnlByCode.children.length > 0) {
            let activeChnlByCode = frm.activeChnlByCode;
            for (i = 0; i < activeChnlByCode.length; i++) {
                if (activeChnlByCode[i].value == activeAssignedChnlByCode.value) {
                    activeChnlByCode[i].disabled = false
                    activeAssignedChnlByCode.removeChild(
                        activeAssignedChnlByCode.options[activeAssignedChnlByCode.selectedIndex]
                    )
                }
            }
        }
    } else if (document.getElementById("Status4").style.display == 'inline') {
        if (assignedInactiveChnlByCode.children.length > 0) {
            let inactiveChnlByCode = frm.inactiveChnlByCode;
            for (i = 0; i < inactiveChnlByCode.length; i++) {
                if (inactiveChnlByCode[i].value == assignedInactiveChnlByCode.value) {
                    inactiveChnlByCode[i].disabled = false
                    assignedInactiveChnlByCode.removeChild(
                        assignedInactiveChnlByCode.options[assignedInactiveChnlByCode.selectedIndex]
                    )
                }
            }
        }
    }
    adminForm.empNumber.value = document.getElementById("employeeNumberValue").textContent;
    clearSearchBoxes();
}

Adding branches to a star using JavaScript

I’m still a beginner at programmation and I am currently working on a script aiming at creating a 5-branch star and adding new branches whenever I click onto the button in the middle of the star. I advanced a lot already but I’m blocked at the Java stage, since I can’t manage to get the new branches spawning at the star’s centre.
Here is my code so far:

console.log("Test")

window.addEventListener('DOMContentLoaded', () => {
  const centre = document.getElementById("centre");

  let compteurBranches = 0;
  centre.querySelectorAll(":scope > div").forEach(el => {
    el.style.setProperty("--image-numero", compteurBranches);
    compteurBranches++;
  });

  centre.style.setProperty("--compteur-branches", compteurBranches);

  document.getElementById("bouton").addEventListener("click", (event) => {
    event.preventDefault();

    const imageNumero = compteurBranches;
    const html = `<div style="--image-numero:${imageNumero};"><img src="branch.png" class="image"></div>`;
    centre.insertAdjacentHTML("afterbegin", html);

    compteurBranches++;
    centre.style.setProperty("--compteur-branches", compteurBranches); 
  });
});
main{
    font-family: "Montserrat", sans-serif;
}

div#main {
    width: 900px;
    height: 900px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;

}

div#centre {
    position: absolute;
    height: 0px;
    width: 100%;
    top: 50%;
    left: 50%;
    display: inline-block;
}

button#bouton{
    width: 200px;
    height: 200px;
    filter: drop-shadow(0px 0px 8px black);
    border: 1px black solid;
    border-top-left-radius: 100px;
    border-top-right-radius: 100px;
    border-bottom-left-radius: 100px;
    border-bottom-right-radius: 100px;
    z-index: 1;
    left: 50%;
    top: 0px;
    position: absolute;
}

div#centre > div { 
    position: absolute;
    z-index: 0;
    background-repeat: no-repeat;
    --angle: calc(90deg + var(--image-numero) * 360deg / var(--compteur-branches));
    transform: rotate(var(--angle));
}


.image {
    transform: rotate(calc(-1 * var(--angle)));
    filter: hue-rotate(var(--angle));
    background-image: url(./branch.png);
    background-repeat: no-repeat;
    transform-origin: top;
    width: 200px;
    height: 344px;
    position: absolute;
    left: 50%;
    top: 100px;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="dm.css">
    <title>DM</title>
</head>
<body>
    <div id="main" style="--compteur-branches:5;"> 
        <div id="centre">
            <div class="image" id="image1" style="--image-numero:0;"></div>
            <div class="image" id="image2" style="--image-numero:1;"></div>
            <div class="image" id="image3" style="--image-numero:2;"></div>
            <div class="image" id="image4" style="--image-numero:3;"></div>
            <div class="image" id="image5" style="--image-numero:4;"></div>
            <button id="bouton">
                Cliquer pour ajouter une branche
            </button>
        </div>
    </div>
</body>
<script type="text/javascript" src="dm.js"></script>
</html>

Client (JRE) read server (node) variables directly?

I am trying to set up a server where clients can connect and essentially “raise their hand”, which lights up for every client, but only one at a time. I currently just use the express module to send a POST response on button-click. The server takes it as JSON and writes it to a file. All the clients are constantly requesting this file to check the status to see if the channel is clear.

I suspect there is a more streamlined approach for this, but I do not know what modules or methods might be best. Can the server push variables to the clients in some way, instead of the clients constantly requesting a file? Then the client script can receive the variable and change the page elements accordingly?

Vue 3 mobile event listeners and swipe

In Vue 3, I want to trigger a function when a user swipes left / right. (I made a calendar and interested in having months changed on swiping)

I found this package: https://github.com/robinrodricks/vue3-touch-events (npm install vue3-touch-events) but it’s not working and I get the following errors:

and imported the relevant packages in main.js:

import Vue from "vue";
import Vue3TouchEvents from "vue3-touch-events";

and in public/index.html:

    <script src="https://raw.githubusercontent.com/robinrodricks/vue3-touch-events/master/index.js"></script>

after that, in main.js
If registered as:

createApp(App)
  .use(Vue3TouchEvents)

then I get the error: “Maximum recursive updates exceeded in component …”
And the event won’t be fired.

If registered as

Vue.use(Vue3TouchEvents);

then I get the error “export ‘default’ (imported as ‘Vue’) was not found in ‘vue'”
And the event still won’t be fired

What’s wrong? How to implement it right or make a solution in another way?
(@starttouch and mobile event listeners seems to not be supported in Vue 3)

MoxieManager TinyMCE

I have purchased MoxieManager and successfully set it up.

I can navigate to the moxiemanager-php-pro directory and see the UI below:
enter image description here

However, through the TinyMCE textbox when clicking to open the UI I see the below error:

‘Authentication failed. Server returned HTTP status: 0’

The only error I see in console is

‘TypeError: undefined is not an object (evaluating
‘moxman.ui.FloatPanel’)’

Javascript unable to capture the mouse position in dedicated variables, when I can easily print it out

So, I am getting back into javascript coding, and I am resuming an older project. I am attempting to capture the mouse position in dedicated variables (mouseX and mouseY), for ease of use.

I have successfully managed to print out the mouse coordinates in real time, but when I try to place those coordinates into dedicated variables for ease of use, the program fails.

I believe this is most likely a simple syntax error, but I don’t know where else to look for what I’m doing wrong.

This code fragment works correctly:

document.addEventListener('mousemove', (event) => {
document.getElementById("fiddleText").innerHTML = (`Mouse X: ${event.clientX}, Mouse Y: ${event.clientY}`);

})

However, when I try to store the mouse position in two variables, like so:

document.addEventListener('mousemove', (event) => {

mouseX = ${ event.clientX };
mouseY = ${ event.clientY };
document.getElementByID("fiddleText").innerHTML = ('Mouse X: ' + mouseX + 'Mouse Y: ' + mouseY);
})

the program fails.

I’d like to imagine that my question can be answered using only the code shown above, but last time I believed that, I was mistaken. As such, I have pasted my full javascript program below.

Note: This program is a work-in-progress, and there is a comment header stating “this is the problem area”; ignore this for now, that is an unrelated issue. Right now, I’m just trying to get the mouse to work.

//canvas elements
var canvas = document.getElementById("SnekGamCanvas");
var ctx = canvas.getContext("2d");
canvas.addEventListener('click', function () { }, false);

/*
//some code from stack overflow: (https://stackoverflow.com/questions/9880279/how-do-i-add-a-simple-onclick-event-handler-to-a-canvas-element)
var elem = document.getElementById('canvas'),
    elemLeft = elem.offsetLeft + elem.clientLeft,
    elemTop = elem.offsetTop + elem.clientTop,
    context = elem.getContext('2d'),
    elements = [];

// Add event listener for `click` events.
elem.addEventListener('click', function (event) {
    var x = event.pageX - elemLeft,
        y = event.pageY - elemTop;

    // Collision detection between clicked offset and element.
    elements.forEach(function (element) {
        if (y > element.top && y < element.top + element.height
            && x > element.left && x < element.left + element.width) {
            alert('clicked an element');
        }
    });

}, false);

// Add element.
elements.push({
    colour: '#05EFFF',
    width: 150,
    height: 100,
    top: 20,
    left: 15
});

// Render elements.
elements.forEach(function (element) {
    context.fillStyle = element.colour;
    context.fillRect(element.left, element.top, element.width, element.height);
});
*/
//End of code from stack overflow


//some important variables
var px = canvas.width / 2;
var py = canvas.height / 2;

var snekColor = "#EC942D";

var clock = 0;

var mouseX = 0.5;
var mouseY = 0.5;

//classes

class clickButton {
    constructor(text, color, width, height, radius) {
        this.text = text;
        this.color = color;
        this.width = width;
        this.height = height;
        this.radius = radius;
    }

    drawButton(xpos, ypos) {
        ctx.strokeStyle = "#000000"
        ctx.fillStyle = this.color;

        roundRect(xpos, ypos, this.width, this.height, this.radius, true, true, this.color);

        ctx.fillStyle = "#000000";
        ctx.strokeStyle = "#000000";
        ctx.font = '40px san-serif';

        ctx.strokeText(this.text, xpos + 10, ypos + 40);
        ctx.fillText(this.text, xpos + 10, ypos + 40);

        //draw_Ball(303, 500, 50, snekColor);
    }

    clickOnButton() {

    }

}

//buttons

var startButton = new clickButton("Start Game", "#74B5ED", 200, 50, 20);

//images
var seel = new Image();
seel.onload = function () {
    ctx.drawImage(seel, 0, 0, canvas.width, canvas.height);
}
seel.src = "https://assets.pokemon.com/assets/cms2/img/pokedex/full/086.png"

var snek_title = new Image();
snek_title.onload = function () {
    ctx.drawImage(snek_title, 0, 0, canvas.width, canvas.height);
}
snek_title.src = "https://globin347.com/images/Snake%20Title.png"

//stuff about mouse moving

document.addEventListener('mousemove', (event) => {
    //document.getElementById("fiddleText").innerHTML = (`Mouse X: ${event.clientX}, Mouse Y: ${event.clientY}`);

    
    mouseX = ${ event.clientX };
    mouseY = ${ event.clientY };
    document.getElementByID("fiddleText").innerHTML = ('Mouse X: ' + mouseX + 'Mouse Y: ' + mouseY);
    
})

//begin
var gameState = 0;

function draw() {

    clock += 1;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    //document.getElementById("fiddleText").innerHTML = ("Clock: " + clock);

    if (gameState == 0) {
        //this hasn't been implemented yet
        startMenu();
    }
    else if (gameState == 1) {
        //this hasn't been implemented yet either
        playGame();
    }
    else if (gameState == 2) {
        //ditto
        gameOver();
    }
    else {
        //something's wrong

        ctx.drawImage(seel, 0, 0, canvas.width, canvas.height);

        ctx.fillStyle = "#b30000";
        ctx.strokeStyle = "#000000";
        ctx.font = '140px san-serif';

        ctx.fillText('OH NO', 120, 120);
        ctx.strokeText('OH NO', 120, 120);

        ctx.fillText('IT BLOKE', 200, 630);
        ctx.strokeText('IT BLOKE', 200, 630);
    }

}
setInterval(draw, 10);

function startMenu() {
    ctx.drawImage(snek_title, 0, 0, canvas.width, canvas.height);

    /***********************************************
     * 
     * 
     * This is the problem area. When the next line, startButton.drawButton(100, 100) is commented out, the rest of the code workes normally.
     * However, if the line is not commented out, draw_Ball doesn't run, indicating that the program crashed somewhere in the button code.
     * I would like to reiterate that the button's functionality has not yet been implemented; I am only trying to get it to display.
     * 
     * 
     **********************************************/

    //startButton.drawButton((canvas.width / 2) - 100, (canvas.height * (4 / 5)));

    //flashing lights
    /*flashTime = timer % 100;
    if (timer % 2) {
        draw_Ball(200, 700, 50, snekColor);
    }*/

    draw_Ball(200, 700, 50, snekColor);
}

function playGame() {
    draw_Ball(200, 700, 50, snekColor);
    draw_Ball(400, 700, 50, snekColor);
    draw_Ball(300, 500, 50, snekColor);
}

function gameOver() {

}

//this function was stolen from stack overflow
function showImage(width, height, image_source, alt_text) {
    var img = document.createElement("img");
    img.src = image_source;
    img.width = width;
    img.height = height;
    img.alt = alt_text;

}

function draw_Ball(bx, by, size, ballColor) {
    ctx.beginPath();
    ctx.arc(bx, by, size, 0, (Math.PI * 2));
    ctx.fillStyle = ballColor;
    ctx.fill();
    ctx.strokeStyle = "#000000";
    ctx.stroke();
    ctx.closePath();
}

//This next function was taken from stack overflow

function roundRect(x, y, width, height, radius, stroke, fill, color) {
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    if (stroke) {
        ctx.stroke();
    }
    if (fill) {
        ctx.fill();
    }
    ctx.closePath();
    return;
}

And, for good measure, my HTML and CSS files:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Portfolio</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body class="background_gradient">
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark dark-bg border-bottom box_shadow mb-0">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Portfolio</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <!--
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                        -->
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Resume">Resume</a>
                        </li>
                        <!----
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Art3D">3D Art</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Art2D">2D Art</a>
                        </li>
                        <!---->
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Snake">Snake</a>
                        </li>
                        
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="CodeExamples">Code Examples</a>
                        </li>

                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Ballad">Ballad of the Masked Bandits</a>
                        </li>
                        <!--
    <li class="nav-item">
        <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="DataBaseHub">Database Hub</a>
    </li>
    --->
                        <!--
    <li class="nav-item">
        <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Unavailable">???</a>
    </li>
        -->
                        <!--Temporary Links-->
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container-fluid" id="MainDiv">
        <main role="main" class="pb-0" style="width:100%">
            <!--Where the other code goes-->
            
                @{
                    ViewData["Title"] = "Snake Game";
                }
                
                <div class="container-fluid purple_gradient text-center">
                    <h1>Snake Game</h1>
                </div>
                <div class="buffer"></div>
                <div class="container">
                    <div class="fancy_text_box">
                        <div class="container buffer">
                            <div class="ghostly_text_box text-center">
                                <h1>By the power of Javascript, here is a playable snake game.</h1>
                                <div class="buffer"></div>
                                <h1 id="fiddleText">Give it a moment to load.</h1>
                            </div>
                
                            <div class="buffer"></div>
                
                            <div class="ghostly_text_box text-center">
                                <canvas onload="draw()" class="simple_text_box" id="SnekGamCanvas" width="1000" height="1000"></canvas>
                            </div>
                
                        </div>
                
                    </div>
                
                    <div class="text-center">
                        <div class="buffer"></div>
                
                        <a class="button glo_button big_r_button big_text" asp-area="" asp-controller="Home" asp-action="Index">Back to Home</a>
                
                        <div class="buffer"></div>
                    </div>
                
                    <!--The code be here but if you are reading this you probably already knew that-->
                    <script src="~/js/Snake.js"></script>
                
                </div>
                
        </main>
    </div>

    <footer class="border-top footer dark-bg text-light">
        <div class="container">
            &copy; 2021 - Portfolio - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    <script src="../jsc3d-master/jsc3d/jsc3d.js"></script>
    @RenderSection("Scripts", required: false)
</body>
</html>


/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */

a.navbar-brand {
  white-space: normal;
  text-align: center;
  word-break: break-all;
}

/* Provide sufficient contrast against white background */
a {
  color: #0366d6;
}

.btn-primary {
  color: #fff;
  background-image: linear-gradient(30deg, #b6e2dd, #2a5efe);
  border-color: #1861ac;
}

/*Link colors*/
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
  color: #fff;
  background-color: #1b6ec2;
  border-color: #1861ac;
}

/* Sticky footer styles
-------------------------------------------------- */
html {
  font-size: 14px;
}
@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.border-top {
  border-top: 1px solid #e5e5e5;
}
.border-bottom {
  border-bottom: 1px solid #e5e5e5;
}

.box-shadow {
  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}

button.accept-policy {
  font-size: 1rem;
  line-height: inherit;
}

/* Sticky footer styles
-------------------------------------------------- */
html {
  position: relative;
  min-height: 100%;
}

body {
  /* Margin bottom by footer height */
  margin-bottom: 60px;
}
.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  white-space: nowrap;
  line-height: 60px; /* Vertically center the text there */
}

/* My Stuff
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--------------------------------------------------------------------------
*/

/*This gives me more control over the exact dark background color*/
.dark-bg
{
    background-color: #161631;
}

.purple_gradient 
{
    /*The image used*/
    background-image: linear-gradient(#4b1ac4, #fff);

    height:100%;
    width:100%;

    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
}

.test_box_blue
{
    /* A container with a solid color and an outline */
    background-color: #2d1eb2;

    width: 100%;
    height: 100%;
    margin: 0px;

}

.test_box
{
    border:solid #000000;
}

#MainDiv
{
    padding:0;
    margin:0;

    left:0;
    top:0;

    width:100%;
    height:100%;
}

.tundra_backround
{
    background-image: url('../images/Tundra_Fixed.png');
    width:100%;
    height:100%;
}

.white_space_box
{
    height:50 px;
}

.background_gradient
{
    background-image:linear-gradient(320deg, #fff, #96cbde);
}

.glo_button
{
    min-width: 30%;
    height: 20%;
    border-radius: 25px;
    padding: 20px;
    margin: 10px;
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
    transition-duration: 0.4s;
    border: 4px solid #000;
}

.big_r_button {
    background-color: #a10000;
    color: #fff;
}

.big_r_button:hover {
    color: #fff;
    background-color: #4e0505;
}

.big_b_button {
    background-color: #080e9f;
    color: #fff;
}

.big_b_button:hover {
    color: #fff;
    background-color: #161631;
}

.big_g_button {
    background-color: #0a7727;
    color: #fff;
}

.big_g_button:hover {
    color: #fff;
    background-color: #07340e;
}

.big_p_button {
    background-color: #6f1cbf;
    color: #fff;
}

.big_p_button:hover {
   color: #fff;
   background-color: #2a073e;

}

.buffer
{
    padding: 20px;
}

.big_text
{
    font-size: 60px;
    font-family:'Times New Roman', Times, serif;
    text-shadow: 2px 2px rgb(12 14 39 / 0.67);
}

.fancy_text_box{
    background-image: linear-gradient(300deg, #ece1c4, #c99e69);
    border-radius: 25px;
    border: 4px solid #5d3c08;
}

.simple_text_box{
    background-color: #fff;

    border: 2px solid #000;
}

.ghostly_text_box{
    background-color: rgb(255 255 255 / 0.60);
    border-radius: 25px;
    padding: 10px;
    border: 3px solid #000;
}

.thick_border{
    border: 4px solid #000;
}

.black_and_white_gradient{
    background-image: linear-gradient(310deg, #fff, #000);
}

.red_border{
    padding: 0px;
    margin: 0px;
    border: 4px solid #8f0000;
}

.model_box{
    border: 4px solid #000;
    background-color: #fff;
    border-radius: 25px;
}

.image_box{
    border: 4px solid #000;
    background-color: #fff;
}

.chain_image_box {
    border-top: 4px solid #000;
    border-left: 4px solid #000;
    border-right: 4px solid #000;
    border-bottom: 0px;
    background-color: #fff;
}

.margin_setter {
    margin: 20px;
    padding: 20px;
}

#model_display_1{

}

I apologize for asking such a simple question, but I don’t know where to look to find an existing answer.

Mapbox popups in a React app not showing up after deploying to Heroku

I have a Mapbox installed in my React app which shows up popups, but only when working in localhost. When I deploy to Heroku the styles look broken. They look a bit faded so I guess it’s the styles which are broken, but I’m a bit lost wondering what I could change. We are also using bootstrap to style some components.

Popup in localhost /
Popup in Heroku

This is the styles file in apps.css

.mapboxgl-popup-content{
  background: none !important;
  padding: 0 !important;
}

.popup-border {
  background: linear-gradient(to right, rgb(255, 189, 65), rgb(255, 200, 255));
  padding: 4px;
  border-radius: 10%;
  opacity: 100%;
}

.popup-content {
  margin: auto;
  color: black;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  border-radius: 10%;
  background-color: white;
  min-width: 250px;
  opacity: 85%;
}

.popup-title {
  padding: 0px 20px;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.popup-description {
  margin: 0;
  padding: 0px 20px;
  align-items: flex-start;
  justify-content: center;
  text-align: center;
}

.popup-owner-attendees {
  display: flex;
  flex-direction: row;
  justify-content: space-evenly;
  text-align: center;
  padding: 0px 20px;
}

.popup-list-title {
  text-decoration: underline;
}
.orange-text {
  color: orange;
  border-bottom: 1px solid orange;
}

In case it helps, this is also the code for the popup inside the React component:

     {selectedEvent ? (
        <Popup
          latitude={selectedEvent.location[1]}
          longitude={selectedEvent.location[0]}
          onClose={() => {
            setSelectedEvent(null);
          }}
        >
          <div>
            <br />
            <h4>
              {selectedEvent.icon} {selectedEvent.title}
            </h4>
            <p>{selectedEvent.description}</p>
            <p>
              Host:
              {selectedEvent.owner
                ? "@" + selectedEvent.owner.username
                : "Anonymous"}
            </p>
            <p>
            {/* ATTENDEES IS NOT BEING POPULATED  */}
              Attendees:
              <ul>
                {selectedEvent.attendees.map((attendee) => {
                  return <li>{attendee.username}</li>;
                })}
              </ul>
            </p>
          </div>
        </Popup>
      ) : null}