Failure to add a visible label to ChartJSImage on doughnut chart

I want to make a doughnut chart where each arc has a string of a particular format. There are limited options in ChartJSImage and I am wondering if it is even possible. To make it clearer, the first picture is what I am getting and the second picture is what I want.

  1. What I am getting
    What I am getting

  2. What I want
    What I want

The issue looks easy, but I feel like ChartJSImage is very limited and I can’t find a solution to it. Here is my code that I tried

const line_chart =  ChartJSImage().chart({
  "type": "doughnut",
  "data": { 
  labels: [
    'Carbs',
    'Protien',
    'Fats'
  ],
  options: {
  plugins: { 
    legend: { // i assumed that I had to put the legend key? still did not work.
      display: true,
      position: 'top',
      align: 'center'
    }
  }
},
datasets: [{
  label: 'Calorie Intake',
  data: [300, 50, 100], // I want to use each number in the array and then 'cal'
  backgroundColor: [
    'rgb(255, 99, 132)',
    'rgb(54, 162, 235)',
    'rgb(255, 205, 86)'
  ]
}],

}}) // Line chart
.backgroundColor('white')
.width(500) // 500px
.height(300); // 300px

line_chart.toFile('myimg.png')

If it is even possible to add labels to a doughnut using ChartJSImage, then please tell me how.

Thanks in advance

req.session losses its userId parameterthat I set in /login . When I try to access req.session again from /check-auth it doesn’t contain userId

So when I set req.session.user in /login, console.log() shows that req.session contains userId however when I try to access req.session in /check-auth I can’t access the session.

const express = require("express");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const cors = require("cors");

const users = require("./models/user");

const app = express();
const port = 8000;
const saltRounds = 10;

const mongoDB = "mongodb://127.0.0.1:27017/project]";
mongoose
    .connect(mongoDB, { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => console.log("Connected to database"))
    .catch((error) => console.error("Error connecting to database:", error));
const db = mongoose.connection;

db.on("error", console.error.bind(console, "MongoDB connection error:"));

db.on("connected", function () {
    console.log("Connected to database");
});

app.use(
    session({
        secret: "Super secret secret",
        cookie: {
            maxAge: 24 * 60 * 60 * 1000,
            domain: "localhost",
            secure: false,
            httpOnly: true,
        },
        resave: false,
        saveUninitialized: false,
        store: MongoStore.create({
            mongoUrl: "mongodb://127.0.0.1:27017/project",
        }),
    })
);

app.use(
    cors({
        origin: "http://localhost:3000",
        methods: ["POST", "PUT", "GET", "OPTIONS", "HEAD"],
        credentials: true,
    })
);

app.use(express.json());

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`);
});

process.on("SIGINT", () => {
    console.log("Server closed. Database instance disconnected");
    server.close(() => {
        db.close(() => {
            process.exit(0);
        });
    });
});

app.post("/login", async (req, res) => {
    try {
        let { username, password } = req.body;
        let user = await users.findOne({ username: username });

        if (user && (await bcrypt.compare(password, user.passwordHash))) {
            req.session.userId = user._id;
            req.session.save();
            console.log("Session:", req.session);
            res.status(200).send("Login successful!");
        } else {
            res.status(401).json({ error: "Invalid credentials" });
        }
    } catch (error) {
        console.error("Internal server error", error.message);
        res.status(500).json("Internal server error");
    }
});

app.get("/check-auth", async (req, res) => {
    try {
        console.log("Session in check-auth:", req.session);
        console.log("Session User:", req.session.userId);
        if (req.session && req.session.userId) {
            let user = await users.findById(req.session.userId);
            console.log("User Details:", user);
            if (user) {
                res.status(200).json({ authenticated: true, user });
            } else {
                res.status(401).json({ authenticated: false });
            }
        } else {
            res.status(200).json({ authenticated: false });
        }
    } catch (error) {
        console.error("Error checking authentication: ", error);
        res.status(500).json({
            authenticated: false,
            error: "Internal server error",
        });
    }
});

I mean I don’t really know what else to try, I am very new to backend web development., i want to check if a session already exists and get user information using it, however req.session doesn’t seem to keep the saved parameters.

Check case of letter in Javascript

Is there another way to check for the case of a letter in a string? I currently use

let letter = String.fromCharCode(Math.round(Math.random() * 100/(100/26))) // sets letter to a random letter
if (letter.toUpperCase() == letter) {
    //insert thing to happen here
}

I apologize if there is another question asking this, I didn’t see one when i checked

Is grouping values with ( value1 || value2) for comparisons valid in JavaScript or TypeScript and if so, why not?

I am wondering if grouping values with || while comparing a single variable value is considered valid in the latest JavaScript or TypeScript and if not, does anyone know a reason for this to not become valid syntactic sugar at some point? Or if it is allowed, in what version of JS was this added and what is this type of shortcut comparison called?

const exampleVar: 'a' | 'b' | 'c' | 'd' = 'a'

// I want to see if example var is 'a' or 'b'
if ( exampleVar === ( 'a' || 'b') ) {
  console.log('Yay!');
} else {
  console.log("Not 'a' or 'b' - Boo!");
}

I would expect this to return true if exampleVar is ‘a’ or ‘b’. It works in console in an evergreen browser so I think my two biggest questions are where can this be safely used and what is this shortcut called so I can check its support in something like CanIUse.

Uncaught ReferenceError: concprop is not defined

I made a simple code for understanding code pen.

<div>
  <span class='title' > Concrete Properties </SPAN>
</div>
<div>
  <span class='keyword'> m<SUB>c</SUB>  </span>
  <span class='equal'>= </span>
    <INPUT id='mc' type='text' value='2300'/>
  <span class='unit' >kg/m<sup>3</sup>  </span>
</div>
<div>
  <span class='keyword'> f<SUB>ck</SUB> </span>
  <span class='equal'>= </span>
    <INPUT id='fck' value='50'/>
  <SPAN class='unit'>MPa</SPAN>
</div>
<button  onclick = "concprop()" > Click</button>
concprop() ;
function concprop() {
}

but i got “Uncaught ReferenceError: concprop is not defined
at https://cdpn.io/cpe/boomboom/index.html?key=index.html-2f21023a-9843-ec6c-017e-1780ac97ec0c:94″ whenever I click button.

I also tried to use

<body onload = 'concprop()'>

by searching a similiar question from other’s.

but it doesn’t work.

Any experts to help me to solve this problem?

I can’t figure out how to solve it.

my code is as below

https://codepen.io/woluck/pen/zYboKea

Thanks in advance!!

[React]Uncaught TypeError: Cannot read properties of null (reading ‘type’)

I’m trying to use react, firebase and semantic ui to make a website that can upload diaries with picture, but when I upload a diary with no picture, it show

Uncaught TypeError: Cannot read properties of null (reading 'type') at Object.onSubmit (NewPost.js:41:1)

When I first finish this code, it’s ok not to upload the photo, I don’t know why it turn out like this.

const [file, setFile] = React.useState(null);
const previewUrl = file ? URL.createObjectURL(file) : "https://react.semantic-ui.com/images/wireframe/image.png";
function onSubmit() {
        setIsLoading(true);
        const documentRef = firebase.firestore().collection(firebase.auth().currentUser.uid).doc();
        const fileRef = firebase.storage().ref('post-images/'+documentRef.id);
        const metadata = {
            contentType: file.type,  //problem here
        };

How do i inherit this component

I got a problem where i need a Function to make that a Start button generate a save Pop up and when to do so, save the Layout on the Old LAyout.

In this moment What it does is tracking Every modification on the layout and Saveit automaticclay int the Old layout, i dont know how to build these here beacuse it work on diferents compontenes, the botton on Action BAR and the layout manipulation on the Pivot Grid compo

this are the funciton for the pivto grid component tahta handle the save and changes on the table

//==================================================================================
//================= HANDLE SAVE AND DISCARD CHANGES =======================
//==================================================================================
const saveChanges = async () => {
console.log(pivotGridDetails);
const savedPivotTableDetails = localStorage.getItem(props.selectedItemInSidePanel.value + LocalStorageType.PivotgridDetails);
const selectedItemInSidePanel = localStorage.getItem(“savedSelectedItemInSidePanel”);
let pivotgridDto: IPivotgridDto = nullPivotgridDto;
pivotgridDto.name = selectedItemInSidePanel ? JSON.parse(selectedItemInSidePanel).value : props.selectedItemInSidePanel.value;

if (savedPivotTableDetails) {
  localStorage.setItem(props.selectedItemInSidePanel.value + LocalStorageType.PivotgridOldDetails, savedPivotTableDetails);
  const parsedSavedPivotTableDetails: ISavedPivotTable = JSON.parse(savedPivotTableDetails);
  parsedSavedPivotTableDetails.areFiltersSet = true;
  setPivotGridDetails(parsedSavedPivotTableDetails);

  pivotgridDto.datasourceId = parsedSavedPivotTableDetails.dataSourceId;
  pivotgridDto.selectedTable = parsedSavedPivotTableDetails.selectedTable;
  pivotgridDto.filters = JSON.stringify(
    parsedSavedPivotTableDetails.filters.map((filter: IFilter) => {
      filter.value = "";
      return filter;
    })
  );
  pivotgridDto.parameters = JSON.stringify(parsedSavedPivotTableDetails.parameters);
  pivotgridDto.calculatedFields = JSON.stringify(pivotgrid.calculatedFields);
  pivotgridDto.numberFieldsFormat = JSON.stringify(pivotgrid.numberFieldsFormat);
  pivotgridDto.description = props.selectedItemInSidePanel.pivotgrid ? props.selectedItemInSidePanel.pivotgrid.description : "";
  pivotgridDto.authorId = 0;
  pivotgridDto.description = pivotgrid.description;
  pivotgridDto.showColumnGrandTotals = props.selectedItemInSidePanel.pivotgrid ? props.selectedItemInSidePanel.pivotgrid.showColumnGrandTotals : false;
  pivotgridDto.showColumnTotals = props.selectedItemInSidePanel.pivotgrid ? props.selectedItemInSidePanel.pivotgrid.showColumnTotals : false;
  pivotgridDto.showRowGrandTotals = props.selectedItemInSidePanel.pivotgrid ? props.selectedItemInSidePanel.pivotgrid.showRowGrandTotals : false;
  pivotgridDto.showRowTotals = props.selectedItemInSidePanel.pivotgrid ? props.selectedItemInSidePanel.pivotgrid.showRowTotals : false;
  pivotgridDto.creationDate = "";
  pivotgridDto.lastEditorId = props.userSession.userId;
  pivotgridDto.lastEditDate = getDateForLogging();
}

if (props.selectedItemInSidePanel.pivotgrid) {
  const optionsToSave = {
    method: "PUT",
    headers: {
      Authorization: `Bearer ${props.userSession.token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(pivotgridDto),
  };

  let response = await fetch(APIURL + PIVOTGRIDS + "EditPivotgrid/" + props.selectedItemInSidePanel.pivotgrid.id, optionsToSave);
  let retrievedData = await response.json();

  if (retrievedData.succeeded) {
    props.triggerFetchForItem();
    props.setIsEditModeOn(false);
  } else {
    notify( "error", 3000);
  }
}

};

const saveState = useCallback(
(state: any) => {
if (props.selectedItemInSidePanel.type === “pivotTable” && props.selectedItemInSidePanel.value !== “”) {
const oldSavedPivotTableLayout = localStorage.getItem(props.selectedItemInSidePanel.value + LocalStorageType.PivotgridOldLayout);
if (oldSavedPivotTableLayout === null) {
localStorage.setItem(props.selectedItemInSidePanel.value + LocalStorageType.PivotgridLayout, JSON.stringify(state));

      setPivotGridLayout(oldSavedPivotTableLayout);
    } else {
      const oldSavedPivotTableLayout = localStorage.getItem(props.selectedItemInSidePanel.value + LocalStorageType.PivotgridOldLayout);
      setPivotGridLayout(oldSavedPivotTableLayout ? JSON.parse(oldSavedPivotTableLayout) : null);
    }

    // esto hace que guarde el estado automaticamente  cundo hay una modoficacion en algun parametro
    localStorage.setItem(props.selectedItemInSidePanel.value + LocalStorageType.PivotgridOldLayout, JSON.stringify(state));

    // Sets loading to false here because of the state saving.
    // Once saveState has ran, it saves on LocalStorage the layout and if you select
    // a new layout faster than saveState, then the layout will be outdated.
  }
  setLoading(false);
},
[props.selectedItemInSidePanel]

);

const loadState = useCallback(
(state: any) => {
const localStoredLayout = localStorage.getItem(props.selectedItemInSidePanel.value + LocalStorageType.PivotgridOldLayout);

  const parsedLayout = JSON.parse(localStoredLayout ? localStoredLayout : "{}");
  return parsedLayout;
},
[props.selectedItemInSidePanel]

);
const StartSaveReport = () => {
const localStorageKeyOld = props.selectedItemInSidePanel.value + LocalStorageType.DatagridOldLayout;
const localStorageKeyLayout = props.selectedItemInSidePanel.value + LocalStorageType.DatagridLayout;

// Get the old layout from local storage
const oldLayout = JSON.parse(localStorage.getItem(localStorageKeyOld) || "{}");

// Get the current layout from local storage
const currentLayout = JSON.parse(localStorage.getItem(localStorageKeyLayout) || "{}");

const areLayoutsEqual = (DatagridOldLayout: any, DatagridLayout: any) => {
  return JSON.stringify(DatagridOldLayout) === JSON.stringify(DatagridLayout);
};

// Check if the layouts are different
const isLayoutChanged = !areLayoutsEqual(oldLayout, currentLayout);

// If the layout is not changed, exit the function
if (!isLayoutChanged) {
  const shouldSaveChanges = window.confirm("¿Desea guardar los cambios realizados?");

  if (shouldSaveChanges) {
    // Call the saveState function or perform the necessary actions
    // props.savePivotGridState();
  }
  props.setStartReport(true);
  props.setReportLoading(true);
  return;
}

props.setStartReport(true);
props.setReportLoading(true);

};

const buttonsForBasicReports = [
{
text: “Start”,
icon: “”,
//text:{t(“reportSetupSlideOver.start”)},
customIconSettings: iconCustomSettings_StartButton,
customTextSettings: textCustomSettings_StartButton,
customBackgroundSettings: backgroundCustomSettings_StartButton,
customBorderSettings: borderCustomSettings_StartButton,
onClick: () => {
StartSaveReport();
},
`

How to get only selected value in JS + Laravel

I have a form like this

form input data

in the field ‘Pilih pengelola oleh’, if you select one of the options, it will show another selected option that has been hidden by display:none.

this is my blade

                        <div class="mb-3 row">
                            <div class="col-md-6">
                                <label class="form-label col-form-label">Pilih Pengelolaan Oleh</label>
                                <div class="col-md-12">
                                    <select class="select2 form-control select2-multiple" 
                                        id="pengelola">
                                        <option selected disabled>Pilih Pengelola</option>
                                        <option value="1">Ranting</option>
                                        <option value="2">PCA</option>
                                        <option value="3">PDA</option>
                                    </select>
                                </div>
                            </div>
                            <div class="col-md-6" id="divrantings" style="display: none;">
                                <label class="form-label col-form-label">Pilih Ranting</label>
                                <div class="col-md-12">
                                    <select class="select2 form-control select2-multiple" 
                                        name="ranting" id="rantings" data-placeholder="{{ __('account.placeholder_rantings') }}">
                                    </select>
                                </div>
                            </div>
                            <div class="col-md-6" id="divpcas" style="display: none;">
                                    <label class="form-label col-form-label">Pilih PCA</label>
                                <div class="col-md-12">
                                    <select class="select2 form-control select2-multiple" 
                                        name="pca" id="pcas" data-placeholder="{{ __('account.placeholder_pcas') }}">
                                    </select>
                                </div>
                            </div>
                            <div class="col-md-6" id="divpdas" style="display: none">
                                    <label class="form-label col-form-label">Pilih PDA</label>
                                <div class="col-md-12">
                                    <select class="select2 form-control select2-multiple" 
                                        name="pda" id="pdas" data-placeholder="{{ __('account.placeholder_pdas') }}">
                                    </select>
                                </div>
                            </div>
                        </div>

im using JS to show and hide the select option, this is my JS

$(document).on('change', '#pengelola', function () {
    var val = $(this).val();

  if (val == 1) {
        $.ajax({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                type: 'GET',
                url: '/aum/aumbyranting',
                success: function (data) {
                    $.each(data, function (index, option) {
                        $('#rantings').append($('<option>').val(option.ranting_id).text(option.ranting_name));
                    });
                }
            });

            $('#rantings').html("")
            $('#divrantings').css("display", "initial");
            $('#divpcas').css("display", "none");
            $('#divpdas').css("display", "none");

        } if (val == 2) {
            $.ajax({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                type: 'GET',
                url: '/aum/aumbypca',
                success: function (data) {
                    $.each(data, function (index, option) {
                        $('#pcas').append($('<option>').val(option.pca_id).text(option.pca_name));
                    });
                }
            });
            
            $('#pcas').html("")
            $('#divrantings').css("display", "none");
            $('#divpcas').css("display", "initial");
            $('#divpdas').css("display", "none");

        } if (val == 3) {
            $.ajax({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                type: 'GET',
                url: '/aum/aumbypda',
                success: function (data) {
                    $.each(data, function (index, option) {
                        $('#pdas').append($('<option>').val(option.pda_id).text(option.pda_name));
                    });
                }
            });

            $('#pdas').html("")
            $('#divrantings').css("display", "none");
            $('#divpcas').css("display", "none");
            $('#divpdas').css("display", "initial");
        
        }
});

there is no problem with the show and hide the select option. My problem is every time I select one option and then change to another option, it results the like this
enter image description here

as we can see, in the request is get value from ‘ranting’ and ‘pca’. but actually i just want get the value from the last option that i choose, how bout this problem?

any help will be appreciated

Rotate people at tables so that they don’t meet more than once [closed]

We have T tables, each with a capacity of P people. We require R rotations (i.e. people change seats) but we don’t want the same people to ever meet twice.

I tried to solve this in JS in a Google Sheet. Here’s a copy: https://docs.google.com/spreadsheets/d/1O7OAlORIMyyfLBx_sjrrHYNdbyOd4rAG5udFzCgXaDc/edit#gid=0

The macro imaginatively called UntitledMacro tries to backtrack through all solutions. I deeply apologize to anyone who actually reads it. I am a dinosaur C++ programmer trying to do something quick&dirty in JS.

My question: for which T, P, R does the problem actually have a solution? It sounds like the kind of problem for which there should be well documented theory and algorithms already created.

How to move the button with the sidebar?

I am doing a college project about a personal website and I need some help to make the Button move alongside the sidebar.

The sidebar moves to the right if you click on the hamburger menu and back if you do the same. In that case, the active class is being toggled. My problem is that my introductory accordion and its description text is not positioned and moving in a manner that’s consistent with the sidebar.

I’m a beginner in this subject and I’m trying my best to get a good grade for this project, as you can see, I have put a page and design together.

function show() {
  document.getElementById('sidebar').classList.toggle('active');
}
document.querySelectorAll('.accordion__button').forEach(button => {
  button.addEventListener('click', () => {
    const accordionContent = button.nextElementSibling;
    button.classList.toggle('accordion__button--active');
    if (button.classList.contains('accordion__button--active')) {
      accordionContent.style.maxHeight = accordionContent.scrollHeight + 'px';

    } else {
      accordionContent.style.maxHeight = 0;
    }
  })
})
#rcorners1 {
  border-radius: 25px;
  background: #222222;
  padding: 20px;
  width: 150px;
  height: 100px;
}

a:link,
a:visited {
  background-color: #222222;
  color: white;
  padding: 20px 25px;
  text-align: center;
  text-decoration: none;
}

a:hover,
a:active {
  color: #EFDC75;
}

* {
  margin: 0px;
  padding: 0px;
}

#sidebar {
  position: absolute;
  width: 300px;
  height: 100%;
  background: #000;
  left: -300px;
  transition: .4s;
}

#sidebar ul li {
  list-style: none;
  color: gray;
  font-size: 20px;
  padding: 26px 24px;
  font-family: "Papyrus", fantasy;
}

#sidebar .toggle-btn {
  position: absolute;
  top: 30px;
  left: 330px;
}

.toggle-btn span {
  width: 45px;
  height: 4px;
  background: black;
  display: block;
  margin-top: 4px;
}

#sidebar.active {
  left: 0;
}

svg {
  display: block;
  margin: auto;
}

path {
  stroke-dasharray: 1584.86181640625;
  stroke-dashoffset: 1584.86181640625;
  animation: LineAnimation 3s ease forwards;
  animation-delay: 0.5s;
}

@keyframes LineAnimation {
  to {
    stroke-dashoffset: 0px;
  }
}

h1 {
  font-size: 70px;
  color: white;
  text-align: center;
  font-family: "Trirong", serif;
}

.accordion__button {
  position: absolute;
  top: 100px;
  left: 600px;
  display: block;
  width: 10%;
  padding: 15px;
  border: none;
  border-radius: 25px;
  outline: none;
  cursor: pointer;
  background: black;
  color: white;
  text-align: left;
  transition: background 0.2s;
}

.accordion__button::after {
  content: '25be';
  float: right;
  transform: scale(1.5);
}

.accordion__button--active {
  background: #333333
}

.accordion__button--active::after {
  content: '25b4'
}

.accordion__content {
  position: absolute;
  top: 147px;
  left: 600px;
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.2s;
  padding: 0 15px;
  font-family: sans-serif;
  color: white;
  background: #333333;
  border-radius: 25px;
}
<html>
<title>Website personal</title>

<head>
  <link rel="stylesheet" type="text/css" href="talent.css" />
</head>



<div id="sidebar">
  <div class="toggle-btn" onclick="show()">
    <span></span>
    <span></span>
    <span></span>
  </div>
  <ul>
    <li><a href="da.html" target="_self" id="rcorners1">Acasa</a></li>
    <li><a href="cv.asp" target="_self" id="rcorners1">CV</a></li>
    <li><a href="despremine.asp" target="_self" id="rcorners1">Despre mine</a></li>
    <li><a href="contact.asp" target="_self" id="rcorners1">Contact</a></li>
  </ul>
</div>

<body style="background-color:#222222;">
  <div class="accordion">
    <button type="button" class="accordion__button">Cine sunt eu ?</button>
    <div class="accordion__content">
      <p>Salut! Bine ai venit pe website-ul meu personal. Eu sunt Botezatu Dragos-George, student la Facultatea de Electronică, Telecomunicații și Tehnologia Informației.
      </p>
    </div>
  </div>
  <script src="smecherie.js"></script>
</body>

</html>

I’ve tried to find a position that doesn’t disturb the sidebar when it’s active but it looks bad in my opinion.

My DOM doesn’t update, but the debug says the position is changing

I am trying to create a javascript clicker game, but currently there’s a problem. The gems that appear after you click don’t update, but according to the debug prints I put the position is changing. This is my code:

<!DOCTYPE html>
<html>
    <head>
        <title>Gem Blaster</title>
        <style>
            :root {
                --hitsleft: 5;
            }

            .gem {
                position: absolute;
                border-radius: 100%;
                width: calc(min(calc(var(--hitsleft)), 9) * 10%);
                height: calc(min(calc(var(--hitsleft)), 9) * 10%);
                border: 2px solid black;
                background-color: transparent;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
            }

            .lowerbtn {
                position: absolute;
                border-radius: 100%;
                width: 100%;
                height: 100%;
                border: 2px solid black;
                background-color: transparent;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
            }

            .gamewindow {
                position: absolute;
                overflow: clip;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 500px;
                height: 500px;
                border: 2px solid black;
                background-color: transparent;
            }

            .gem span {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
            }

            .gem span::selection {
                background: transparent;
            }

            #fallenGem {
                --fillcolor: rgb(31, 163, 229);
                position: absolute;
                fill: var(--fillcolor);
                z-index: 2;
                width: 10%;
                height: 10%;
            }
        </style>
    </head>
    <body>
        <div class="gamewindow"> <!-- So the game is always fair even if your screen size is different -->
            <div class="gem"><button onclick="lowerit()" class="lowerbtn"></button><span id="hitsleft">5</span></div>
        </div>

        <script>
            var hitsleft = 5;
            var hitpower = 1;
            var nexthl = 7;
            var r = document.querySelector(":root");

            function lowerit() {
                hitsleft -= hitpower;
                if (hitsleft <= 0) {
                    hitsleft = nexthl;
                    nexthl += Math.round(nexthl * 0.3);
                    console.log("Attempting to run particles()")
                    particles();
                    console.log("Got past particles")
                }
                r.style.setProperty("--hitsleft", hitsleft);
                document.getElementById("hitsleft").innerHTML = hitsleft;
            }

            function particles() {
                console.log("Particles ran!")
                arr = []
                arrvelx = []
                arrvely = []
                arrposx = []
                arrposy = []
                for (var i = 0; i<nexthl; i++) {
                    console.log("Creating Particle...")
                    svg = document.createElement("div")
                    Object.assign(svg, {id: "fallenGem", width: "256", height: "256", viewbox: "0 0 256 256"});
                    svg.innerHTML = "<svg id="fallenGem" viewBox="0 0 256 256"><polygon points="256,128 192,64, 64,64 0,128 128,256"></polygon></svg>"
                    console.log(svg)
                    console.log("adding to body")
                    document.body.appendChild(svg)
                    arr.push(svg)
                    arrvelx.push((Math.random()+1)/2*100)
                    arrvely.push(0)
                    arrposx.push(0)
                    arrposy.push(0)
                }
                while (arr.length > 0) {
                    for (var i = 0; i<arr.length; i++) {
                        svg = arr[i]
                        velx = arrvelx[i]
                        vely = arrvely[i]
                        posx = arrposx[i]
                        posy = arrposy[i]

                        console.log("Particle updated!")
                        svg.style.left = `${posx}%`;
                        svg.style.top = `${-posy}%`;

                        velx *= 0.4;
                        vely *= 0.7;

                        vely += -4;

                        posx += velx;
                        posy += vely;

                        arr[i] = svg
                        arrvelx[i] = velx
                        arrvely[i] = vely
                        arrposx[i] = posx
                        arrposy[i] = posy

                        console.log(posy)

                        if (posy < -100) {
                            console.log("removing one!")
                            arr.splice(i,1)
                            arrvelx.splice(i,1)
                            arrvely.splice(i,1)
                            arrposx.splice(i,1)
                            arrposy.splice(i,1)
                        }
                    }
                }
            }
        </script>
    </body>
</html>

When I look at the console, it says there is no error, and it says that “posy” is lowering, even though the gems just stay in their same random position. I was expecting them to fall, but they just stayed there. I understand that I haven’t implemented deleted the svg object, but I’ll do that later. What I want right now is for the gems to fall down.

ReactJS Updating Context in class component

I am following differents tutorials I found online to use “Context” in ReactJS but I fail to make it work when I want to update the context in child pages. the code I use as a base comes from here : https://www.taniarascia.com/using-context-api-in-react/
I use class components and here is what I have :

The component for context :

import React, { Component } from 'react'

const UserContext = React.createContext()

class UserProvider extends Component {
  // Context state
  state = {
    user: {},
  }

  // Method to update state
  setUser = (user) => {
    this.setState((prevState) => ({ user }))
  }

  render() {
    const { children } = this.props
    const { user } = this.state
    const { setUser } = this

    return (
      <UserContext.Provider
        value={{
          user,
          setUser,
        }}
      >
        {children}
      </UserContext.Provider>
    )
  }
}

export default UserContext
export { UserProvider }

My App.js :

import FooterSPA from './components/FooterSPA/FooterSPA'

import UserContext, {UserProvider}  from './components/Context/UserContext'

// This component is the application entry point
class App extends Page {

  render() {

    const user = { lastname: 'langlois', firstname:"h", loggedIn: true }
    //const {user, setUser} = useState({ lastname: 'langlois', firstname:"hugo", loggedIn: true });

    return (
      <UserContext.Provider value={user}>
          {this.childComponents}
          {this.childPages}
          <FooterSPA homePath={this.props.locationPathname}/>
      </UserContext.Provider>
    );
  }
}

export default withModel(App);

And Finally, the component where I try to do something FooterSPA :

import React, {Component} from 'react';
import {Link} from 'react-router-dom';

import UserContext from '../Context/UserContext'

require('./FooterSPA.css');

export default class Footer extends Component {

  static contextType = UserContext

  render() {

    console.log(this.context);

    const { user, setUser } = this.context

    return (
        <div>
            <button
              onClick={() => {
                const newUser = { name: 'Joe', loggedIn: true }
                setUser(newUser)
              }}
            >
              Update User
            </button>
            <div className="footerspa">
                <div className="footercontainer">
                    <Link to={this.props.homePath}>Back to Home Page</Link>
                </div>
            </div>
        </div>
    );
  }
}

I keep having an error saying that in FooterSP.js, “setUser” is not a function.
I tried to use “this.setUser” or “this.context.setUser” but it’s the same.
I am very new to react and I guess I miss something obvious but I can’t find what.
Also, I’m not sure how the Context.js component I created works so it’s hard so troubleshoot for me.

I hope someone can help me, thank you in advance !
HL

I tried to change my App.js, or pass the function but I don’t have knowledge with React so I don’t even know what to do as a start

I want the sidepanel to show up AND be modified on one click, but it’s requiring two clicks for Chrome extension?

I am creating a Chrome dictionary game extension, and the first part of the project requires a user to be able to right click on a word, and a sidepanel appears with definitions of the word (definitions found using a local database).
However, I am running into a small problem. A user has to right click on the word then press “define” twice, once to pull up the side panel THEN a second time to display the definition.
On the first click, it displays this:
[1]: https://i.stack.imgur.com/wVHsD.png
And on the second click of “WordBank It!” it then displays the definition on the sidepanel:
[2]: https://i.stack.imgur.com/t8CFv.png
I want it to open the side panel and display the definition on one click, obviously for better ease of use. How can I do so? Here are my code files:

// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


function setupContextMenu() {
  chrome.contextMenus.create({
    id: 'define-word',
    title: 'WordBank It!',
    contexts: ['selection']
  });
}

chrome.runtime.onInstalled.addListener(() => {
  setupContextMenu();
});

chrome.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === 'define-word') {
    // This will open the panel in all the pages on the current window.
    chrome.sidePanel.open({ windowId: tab.windowId });
    showDef(info.selectionText);
  }
  
});

function showDef(data) {
    // Hide instructions.
    document.body.querySelector('#select-a-word').style.display = 'none';

    // Show word and definition.
    document.body.querySelector('#definition-word').innerText = data.value;
    document.body.querySelector('#definition-text').innerText = words[data.value.toLowerCase()]; // websearch 
}
<html>
  <head>
    <title>Dictionary Side Panel</title>
  </head>
  <body>
    <h1>Dictionary</h1>
    <hr />
    <p id="select-a-word">Select a word to see the definition.</p>
    <div>
      <h2 id="definition-word"></h2>
      <p id="definition-text"></p>
    </div>
    <script src="service-worker.js"></script>
  </body>
</html>

And then obviously the manifest.json:

{
  "name": "Dictionary side panel",
  "version": "0.1",
  "manifest_version": 3,
  "description": "Provides definitions in the side panel.",
  "background": {
    "service_worker": "service-worker.js"
  },
  "icons": {
    "128": "tayy.png",
    "16": "tayy.png"
  },
  "side_panel": {
    "default_path": "sidepanel.html"
  },
  "permissions": ["sidePanel", "contextMenus"]
}

What should I do?

Update Google Chart from Jquery

I’m using Google Charts with data from mySQL and it provides the results the first time. The php page that has the chart and table results has a dropdown option where the data can be changed. The date updates the mySQL query using a jquery function. See below. The problem is that the Google Chart is not updating when a new date range is provided. Can someone help me with jquery so the chart can be updated on date change.

Thanks
Angel

The Query
$dbDemographicsQuery = "SELECT Race, COUNT(Race) AS totalRace, Ethnicity
FROM Greeter_Detail
WHERE $dateRange
GROUP BY Race";


JQ used to update dates:
$('#month, #year').on('change', function() {
var url = window.location.href;
url += '?month=' + $('#month').val();
url += '&year=' + $('#year').val();
$('#table-data').load(url + ' #table-data > *');
});

RFID scan time sent to html page

I’m using an arduino uno + RFID RC522 connected via usb to my pc. I want it to send to an html page the time of when i swipe a card over the RFID. The nodejs server works and the html page too but the html doesn’t show the information.