How to submit a form that is the result of an XMLHttpRequest inside an empty div, without page refresh?

I’m trying to make a chatroom like website. But I ran into a big problem relating to AJAX.

I have an empty div in the main page inside which I load all the messages that are found in the database using an XMLHttpRequest. It’s all fine so far as I managed to make it work well. But then I wanted to take things to the next level and create an Admin account that would be able to delete any posts in case they contain an inappropriate content. I have added an extra row inside the table that contains a form with a hidden text input which contains the id of the selected row. And I have a button on which I would click, and I would call a file that has the role of deleting the respective entry from the database,

I have tried to submit the form using a regular POST method inside the form without AJAX just to check if it works well on the database. And it works perfectly, so there are no problems in my mysql procedures file. But it refreshes the webpage and I want to avoid that, so AJAX is my only hope, but when I try to use AJAX it just won’t work. I believe this is mainly because the form that I use to delete the posts is in another file than the main body of my website.

I tried some different things but nothing seems to work.
I have noticed that there aren’t many resources regarding the issue I am facing, and I get it, what I want is a bit uncommon as AJAX is most often used to submit text/textarea inputs that are filled by the user and are in a single file. And I already did that myself, in the main page I have a textarea form that I can submit with AJAX without refreshing the page so I kind of understand how it works. But regarding the problem I am facing right now, no resource on the web has proved useful. This thread is the closest to what I am looking for: Submiting a form that is inside a div with AJAX but it doesn’t provide any solutions.

So I’ll post my code here:
The main body of the website is in the file Chatroom.php, here I have the XHR request:

<!DOCTYPE html>
<html>
<body>

function table2(){
    const xhttp = new XMLHttpRequest();
    xhttp.onload = function(){
      document.getElementById("scrollchat").innerHTML = this.responseText;                        
    }
    xhttp.open("GET", "load_chat.php");
    xhttp.send();
  }

  setInterval(function(){
    table2();
  }, 500);

<div id="scrollchat">

</div>

Which is nothing fancy just the classical code which works perfectly fine, the div that I am filling is:
<div id="scrollchat"> </div>

And then in the load_chat.php where I read the contents from the database I have a form that contains the ID of each message which is the following:

<?php
session_start();
//echo '12345';
$con = mysqli_connect('localhost', 'root', '');

mysqli_select_db($con, 'chatroom');
//echo $_SESSION['username1'];
$onlinevalue = 1;

$count = "SELECT * FROM mainchat";

$rows = mysqli_query($con, $count);
$number = mysqli_num_rows($rows);
?>

<table>
<?php 
foreach($rows as $row) : ?>

<td>
$currentuser = $row["Username"];
echo $currentuser;
</td>
<td> 
 <form action="" id="deletepostform">
 <input type="hidden" name="MessagedeleteID" value="<?php echo $row["ID"]; ?>" />
 <button type="submit"> <b><span style="color:red">X</span></b></button> 
 </form>
 </td>
<?php endforeach; ?>
</table>

What would be the best AJAX function that would allow me to submit a form that is returned by this function?

Back in my main page Chatroom.php I tried a lot of types of AJAX calls. What I tried last time is the following code:

document.getElementById('deletepostform').addEventListener('submit', function(event) { event.preventDefault(); // Prevent the default form submission
    let xhr = new XMLHttpRequest();
    let url = 'deletepost.php'; // Replace with your server endpoint
    xhr.open('POST', url, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    
    // Collect form data
    let formData = new FormData(this);
    let params = new URLSearchParams(formData).toString();
    
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.responseText); // Handle the response
        }
    };
    
    xhr.send(params); // Send the request with the form data
    });

And with this code I get the error

TypeError: Cannot read properties of null (reading ‘addEventListener’)

in the console. And I think this may happen because it doesn’t find the form in the main page.

Anything I try can’t submit it because it does not find the actual form in the page itself as it is loaded from somewhere else

Hide spinner/loader when clicking browser back/forward button

I have an css spinner that animates after an anchor link tag is clicked (redirecting to an external webpage/app). However, after the page is finished loading to the external webpage, and the user clicks the browsers back button (and even the forward button), the spinner is still showing. Is there a way to hide the spinner on the event the windows back/forward button is clicked? Or is there a better way to implement the spinner, so that when the user navigates the browsers back and forward button, the spinner gets hidden?

Locally on VScode the spinner does hide after clicking the back button, but after deploying to Github the spinner still displays. From the browser inspector tool, i’ve also cleared the cache/cookie and it still shows.

Work Portfolio link here: https://austinxduong.com/

HTML

<div class="app_link_api_div">

    Apps i recently created: <br /> <br />
    This API connects to an interactive front-end built with React.js. When pasting a url link of a website, it renders a shortened link --- shareable across various social media websites posts</p>

    API: <a href="https://backend-microservice-urlshortener.onrender.com/">https://backend-microservice-urlshortener.onrender.com/ </a> <br /> <br />
                           
</div>

CSS

.loadingDiv {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f7f9fb89;
}

.loadingDiv::after {
  content: "";
  width: 60px;
  height: 60px;
  border: 15px solid #dddddd;
  border-top-color: #1ecd97;
  border-radius: 50%;
  animation: loading 0.75s ease infinite;
}

JavaScript/jQuery

$('a').on("click", function(){
    $('<div class=loadingDiv>loading...</div>').prependTo(document.body); 
 });


$(window).on("click", function(){
    $('<div class=loadingDiv>loading...</div>').hide(); 
 });

I also thought/tried the ‘popstate’ event would hide the div, after the event the window history changes (clicking the windows back button), but still same results also… (maybe because the clicking the back button restores the history’s’ previous state?)

// $(window).on('popstate', function(){
//     $('<div class=loadingDiv>loading...</div>').hide();
// })

Alternatively, I’ve also tried to implement the spinner feature with just Vanilla JavaScript but the results are also still the same. Any suggestions and greatly appreciated! Thank you

HTML

<div class="app_link_api_div">

    Apps i recently created: <br /> <br />
    This API connects to an interactive front-end built with React.js. When pasting a url link of a website, it renders a shortened link --- shareable across various social media websites posts</p>

    API: <a id="btnspinner-0" href="https://backend-microservice-urlshortener.onrender.com/">https://backend-microservice-urlshortener.onrender.com/ </a> <br /> <br />

    <div class="spinner-displayer-0"></div>
                           
</div>

CSS

.loading {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f7f9fb89;
  transition: opacity 0.75s, visibility 0.75s;
}

.loading::after {
  content: "";
  width: 60px;
  height: 60px;
  border: 15px solid #dddddd;
  border-top-color: #1ecd97;
  border-radius: 50%;
  animation: loading 0.75s ease infinite;
}

@keyframes loading {
  from {
    transform: rotate(0turn);
  }

  to {
    transform: rotate(1turn);
  }
}

JavaScript

function spinner0(){
   const spinnerDisplayer0 = document.querySelector('.spinner-displayer-0');
   const btnspinner0 = document.getElementById('btnspinner-0');

   btnspinner0.addEventListener('click', () => {
        spinnerDisplayer0.classList.add('loading');
   })
}
spinner0();

Drawing new Image() onto canvas and using canvas.toDataURL()

I’m playing around on a side project trying to get a button that screenshots an element. I followed the code at Rendering HTML elements to <canvas> to render the element into a canvas, then canvas.toDataURL() to create the image.

I’ve read in various posts here that it’s a problem when loading an image file, or when working on localhost. However I’m getting the error on Netlify as well, in all browers except Firefox (this is expected locally). One suggestion was to set the crossorigin attribute to anonymous which I’ve done, and it has no effect.

I’ve read in a couple of places, including this post that I need to set headers on the image. As it’s coming from new Image() in JS can I set those headers for the whole site safely? Will it fix the problem even if I can?

The relevant part of my code:

    function renderHtmlToCanvas(canvas, html) {
        const ctx = canvas.getContext('2d');

        const svg = `
            <svg xmlns="http://www.w3.org/2000/svg" width="${canvas.width}" height="${canvas.height}">
            <foreignObject width="100%" height="100%">
                    <div xmlns="http://www.w3.org/1999/xhtml">${html}</div>
            </foreignObject>
            </svg>`;

        const svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });
        const svgObjectUrl = URL.createObjectURL(svgBlob);

        const tempImage = new Image();
        tempImage.crossOrigin = 'anonymous';
        tempImage.addEventListener('load', () => {
            ctx.drawImage(tempImage, 0, 0);
            canvasToImage(canvas);
            URL.revokeObjectURL(svgObjectUrl);
        });

        tempImage.src = svgObjectUrl;
    }

    // Convert the canvas to an image
    function canvasToImage(canvas) {
        const image = new Image();
        const screenshotData = canvas.toDataURL('image/webp');
    }

    renderHtmlToCanvas(canvas, html);

How can I force my Next.js project to get new data from my getCart function

I am trying to make a very small ecommerce site for a friend’s pet business but I am having an issue with the cart page on the next.js project to get the correct information.

this is my function for getCart

export async function getCart(): Promise<ShoppingCart | null> {
  const session = await getServerSession(authOptions);

  let cart: CartWithProducts | null = null;

  if (session) {
    cart = await prisma.cart.findFirst({
      where: { userId: session.user.id },
      include: { items: { include: { product: true } } },
    });
  } else {
    const localCartId = cookies().get("localCartId")?.value;
    cart = localCartId
      ? await prisma.cart.findUnique({
          where: { id: localCartId },
          include: { items: { include: { product: true } } },
        })
      : null;
  }

  if (!cart) {
    return null;
  }

this is my cart page

import { getCart } from "@/lib/db/cart";
import CartEntry from "./CartEntry";
import { setProductQuantity } from "./actions";
import { formatPrice } from "@/lib/format";
import HomeIcon from "@mui/icons-material/Home";
import Link from "next/link";
import { getServerSession } from "next-auth";
import { authOptions } from "../api/auth/[...nextauth]/route";
import { revalidatePath } from "next/cache";
import CheckoutButton from "@/components/CheckoutButton";

export default async function CartPage() {
  const session = await getServerSession(authOptions);

  const cart = await getCart();

  revalidatePath("/cart");

  const sortedItems = cart?.items.sort((a, b) => {
    return a.product.name.localeCompare(b.product.name);
  });

  let shippingCost = 299;

  if (cart?.subtotal) shippingCost = cart?.size > 1 ? 0 : 299;

  return (
    <div className="mt-4 sm:mt-0">
      <div>
        <h1 className="mb-2 text-center text-3xl font-bold">Shopping Cart</h1>
        {sortedItems?.length && cart?.subtotal != undefined ? (
          <h2
            style={{ marginBottom: 25 }}
            className="flex flex-col flex-wrap items-center justify-between gap-3 sm:flex-row md:pl-20 md:pr-20 lg:pl-52 lg:pr-52"
          >
            Selected Items
          </h2>
        ) : null}
        {sortedItems?.map((cartItem) => (
          <CartEntry
            cartItem={cartItem}
            key={cartItem.id}
            setProductQuantity={setProductQuantity}
          />
        ))}
        <h4 className="my-10 text-center text-3xl font-bold">
          {!sortedItems?.length && (
            <>
              <p>Your Cart is empty.</p>
              <Link
                href="/"
                className="btn btn-primary mt-16 rounded-full sm:w-[200px]"
              >
                Go To Home Page <HomeIcon />
              </Link>
            </>
          )}
        </h4>
        {sortedItems?.length && cart?.subtotal != undefined ? (
          <>
            <div className="flex flex-col items-center">
              <p className="mb-1">Subtotal: {formatPrice(cart?.subtotal)}</p>
              <div>
                Shipping:{" "}
                {shippingCost === 0 ? (
                  <h2 className="inline font-bold text-green-700">{"Free"}</h2>
                ) : (
                  formatPrice(shippingCost)
                )}
              </div>

              <p className="mt-3 font-bold">
                Total: {formatPrice(cart?.subtotal + shippingCost)}
              </p>
              <p className="my-2 text-xs">* Tax Calculated At Checkout</p>
              <div className="mr-2">
                <CheckoutButton />
              </div>
            </div>
          </>
        ) : null}
      </div>
    </div>
  );
}

and this is the link to take the person to the cart in the navbar

      <Link href="/cart" className="btn btn-primary btn-block">
           View Cart
      </Link>

It doesn’t seem to be an issue with the revalidate path because I console.out what is returned from the cart, which is old information. But Next.js is still new to me, so maybe I am using it wrong. That said, I also tried putting

export const revalidate = 0;

to not cache any information at the top of the cart page, but that doesn’t seem to help either. The only thing that does seem to work is to manually refresh the page or replace my Link to the cart page with

          <button
              className="btn btn-primary btn-block"
              onClick={() => {
                window.location.href = "/cart"; 
              }}
            >
              View Cart
        </button>

This also forces a refresh, but I would prefer not to do it this way since it is a hard refresh and it is not as smooth of a transition. So is there a way I can fix this?

Also, what is noticible is that the navbar cart icon correctly has the items and amount in it, but that is a client side component, while the cart is a server side component. Also, when I try to move on the the actual checkout page which I started making with Stripe, it carries over the correct amount.

MSAL protectedResourceMap VERB based configuration

I’m looking to configure protectedResourceMap with MSAL to differentiate between HTTP verbs. Specifically, I want to set up an open POST endpoint and a protected GET endpoint.
Requirements:

Anonymous POST: When a button is clicked, allow an anonymous action to log that a product has been bought.
Authenticated POST: If the user is logged in, also add the purchase to their account history.
Authenticated GET: Fetching purchase history should only be available to logged-in users.
protectedResourceMap: new Map([
           // Other entries...
          [
            'http://127.0.0.1:5000/api/cart',
            [
              'https://proficiento.onmicrosoft.com/proficiento-api/write',
              'https://proficiento.onmicrosoft.com/proficiento-api/read',
            ],
          ],

Can I configure protectedResourceMap to differentiate between POST and GET requests for these endpoints?
I know i can make it manually, but i dont want to 🙂

Hash CSS Module Styles with Vite

I have a project setup with Nuxt 3 and I am using a css file called grid.module.css. What I want to do is rather than use the default hashed css names that vue provides (.grid becomes ._grid_1a0w7_1), I wanted to setup my own class names so that there is a format something like .grid_grid__XyZ14. Here are the docs for vite’s css module options.

I am not sure if this is the right approach to hash a class name, but I keep getting a slash once in a while / and this causes the css rule to not be applied.

Is this the wrong approach to use crypto, or what would be an elegant solution to hashing a css class name so that something like .grid becomes xYz23 without having to worry about any characters showing up that are not valid in css?

import path from 'path'
import crypto from 'crypto'

defineNuxtConfig({
  vite: {
    css: {
      modules: {
        generateScopedName: (className, filename) => {
          const fileName = path.basename(filename, '.module.css')
          
          const hash = crypto
            .createHash('sha256')
            .update(className)
            .digest('base64')
            .substring(0, 5)

          return `${fileName}_${className}__${hash}`

        }
      }
    }
  }
})

I updated this code to use a recursive function, and had to add a + in the if condition because that character was also being added and causing the css rule to not be applied.

import path from 'path'
import crypto from 'crypto'

defineNuxtConfig({
  vite: {
    css: {
      modules: {
        generateScopedName: (className, filename) => {
          const fileName = path.basename(filename, '.module.css')

          function createHash(hash) {
            const _hash = crypto.createHash('sha256').update(hash).digest('base64').substring(0, 5)

            if (_hash.includes('/') || _hash.includes('+')) {
              return createHash(_hash)
            }

            return _hash
          }

          const hash = createHash(className)

          return `${fileName}_${className}__${hash}`

        }
      }
    }
  }
})

Use Google Material Icons in Vuetify 3 outside a module

I’m working on an existing code base that creates a Vue app within the page. We are attempting to update to Vuetify 3, but for some reason we’re not having any luck getting Google Material Icons to show up in Vuetify elements.

Here is an example: https://codepen.io/TheMissingBit/pen/BaXoyWy

As you can see, I have material icons showing up properly inside of a span, but as soon as I try to specify the same icon inside of a <v-text-field>, the icon is displayed as blank.

I have checked the documentation on the Vuetify website, but it’s all focused on modules, which our code base does not have (and we’re not looking to redo the whole thing at this point). Can anyone point me in the right direction to set the proper iconset?

How to create a continuous custom transformation of an image in a web app

I would like to display the continuous transformation of a photo image in a web app. Transformations would include things like gradually changing the degree to which the image was spiralled in towards the center, so the transformation would look like it is unspiraling back to the original image, or transforming the image into a line drawing and then gradually revealing the line image by continuously revealing points. In addition, and perhaps alternatively, I would want a library for doing matrix operations on the image to create custom transformations. The images will be no greater than 400 x 400 pixels with each pixel having RGBA values. I want to do this image transformation in the browser, so am looking for an image processing/matrix library (Javascript?) that can integrate with a react web app.

How do I Split and filter 2 arrays

I have an 2 Array

var arr1 = ['A','B','C','D']
var arr2 = ['A~XX','A~XXX','B~YY','B~YYY']

I want push arr2 elements that contains ‘A’ to op_array

var op_array = new Array();

my op_array should look like this, If ‘A’ is passed this

['A~XX','A~XXX']

If ‘B’ is passed then

['B~YY','B~YYY']

I have been trying this

op_array = arr1.filter(item => !arr2.split(/~/)[1].includes(item));

Curious to learn an efficient way.

how to remove class from selected dom’s siblings? how to open a div and have all the other ones close? do i use siblings() or what

i have this grid with 3 columns, and i wanted to make it so that when i click one of the divs it’ll go down a row and span the whole row, it also closes back up when i click on it again. and i got that to work. but i wanted to make it so that when i open a different div, itll close all the other ones if theyre open? so that theres only one open at a time? how would i do that?

<div id="gridALBUM">
  <div id="one" onclick="toggles1()">   <h1>1</h1> <div><h2>one</h2></div> </div>
  <div id="two" onclick="toggles2()">   <h1>2</h1> <div><h2>two</h2></div> </div> 
  <div id="three" onclick="toggles3()"> <h1>3</h1> <div><h2>three</h2></div> </div>
  <div id="four" onclick="toggles4()">  <h1>4</h1> <div><h2>four</h2></div> </div>
  <div id="five" onclick="toggles5()">  <h1>5</h1> <div><h2>five</h2></div> </div>
  <div id="six" onclick="toggles6()">   <h1>6</h1> <div><h2>six</h2></div> </div>
  <div id="seven" onclick="toggles7()"> <h1>7</h1> <div><h2>seven</h2></div> </div>
  <div id="eight" onclick="toggles8()"> <h1>8</h1> <div><h2>eight</h2></div> </div>
  <div id="nine" onclick="toggles9()">  <h1>9</h1> <div><h2>nine</h2></div> </div>
  <div id="ten" onclick="toggles10()"> <h1>10</h1> <div><h2>ten</h2></div> </div>
</div>

also, i have these other divs next to the h1 thatll have information in it, but i only want it to show if its parent div got expanded and spanned the whole row? so i want to change the display from hidden to block only IF it got opened.. i know i have to add or remove class hidesINFO but like, would i have to make a function for each div to do that?

#gridALBUM {
  margin: 50px auto;
  max-width: 908px;
  display: grid;
  grid-gap: 0 4px;
  grid-template-columns: repeat(3, 300px);
  background-color: lightblue;
}

#gridALBUM > div {
  border: 1px solid black;
  display: flex;
}

.hidesINFO {
  display: none;
}

.span {
  grid-column: 1 / 4;
  background-color: blue;
}

also, is there a better way to do the code below? instead of having to have the same exact code but with different IDs for each to target each div? because im gonna have to add more divs and i dont want to have to copy and paste each function when theyre really only doing the same thing, just to different elements

function toggles1() {
  document.getElementById("one").classList.toggle("span"); } 

function toggles2() {
  document.getElementById("two").classList.toggle("span"); } 

function toggles3() {
  document.getElementById("three").classList.toggle("span"); } 

function toggles4() {
  document.getElementById("four").classList.toggle("span"); } 

function toggles5() {
  document.getElementById("five").classList.toggle("span"); } 

function toggles6() {
  document.getElementById("six").classList.toggle("span"); } 

function toggles7() {
  document.getElementById("seven").classList.toggle("span"); } 

function toggles8() {
  document.getElementById("eight").classList.toggle("span"); } 

function toggles9() {
  document.getElementById("nine").classList.toggle("span"); } 

function toggles10() {
  document.getElementById("ten").classList.toggle("span"); } 

do i use siblings() to like, remove selectors? like would this work?

function toggles2() {
  document.getElementById("two").classList.toggle("span"); 
  document.getElementById("two").siblings().classList.remove("span");
  document.getElementById("two").siblings().child[1].classList.remove("hidesINFO");}

Only one of 2 JavaScript animations work at a time

I have a responsive website and I need 2 different animations under 2 different script tags to run depending on @media but only one animation will run while the other does absolutely nothing. Im not sure how to make them both work or how to make one run if a certain @media is true.

The “navigation scroll animation” should run for every device except for mobile. The “cta animation” should run for mobile devices (anything 450px and under).

The that the “nav scroll animation affects will not be visible on the mobile layout.

The header button will be displayed on all screen widths but I only want the “cta animation” to take place when the device width is under 450px

The animations only worked if one of the script tags were deleted.

I tried merging the two script tags into the same if statement. I tried using window.matchMedia(). The only thing that partially worked was deleting one of the script tags.

Here is my code:


<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Whimsicss Studio - Websites for Small Businesses</title>

</head>
<body>
<header style="height:1000px;">
<nav id="navigation" style="position: fixed; top:0; width:100%; height:70px; background-color: grey; transition: .8s;">

</nav>
<script> /*navigation scroll animation*/
var prevScrollpos = window.pageYOffset;
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
var currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById("navigation").style.top = "0";
                 
} else {
document.getElementById("navigation").style.top = "-90px";
}
prevScrollpos = currentScrollPos;
}
</script>

<section style="margin-top: 90px;">
<h1>
Websites are more than design, they’re a part of a Strategy
</h1>
<a href="contact.html" class="button" id="header-button" style="display:block; position:fixed; bottom:30vh; background-color:skyblue; width:100px; height:50px; border:2px solid red; transition: 0.8s ease-in-out">
Lets Talk!
</a>
        
<script> /* cta animation*/
var prevScrollpos = window.pageYOffset;
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
var currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById("header-button").style.left = "0.25in";
} else {
document.getElementById("header-button").style.left = "-10in";
prevScrollpos = currentScrollPos;
}
}
</script>
</section>  
            
</header>
        
</body>
</html>

Creating Cd with html & css [closed]

I wanna to create back cd with html & css and rotate the cd when you rotate cd change the color

i ma tryng wuth html and css jusr wanna create a good cd whth html & css if you use js it is ery good for me thanks for help me

onclick of button btn.addEventListener.console.log(“hello”) is not showing. i tried using advance function too

        import {products} from"../html/products.js";
        let productsHTML="";
        products.forEach(x => {
         productsHTML+=`<div class="products">
        <div class="image">
        <img class="img"src="${x.image}" alt="">
        </div>
        <div class="content">
        <div class="productName">${x.name}</div>
        <div class="productPrice">Rs.${x.price}</div>
        <select name="number"  id="productQuantity" class="select">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
            <option value="6">6</option>
            <option value="7">7</option>
            <option value="8">8</option>
            <option value="9">9</option>
            <option value="10">10</option>
        </select>
        <button class="addtocart" >Add To Cart</button>
        </div>
        </div>
        `
         });
         document.querySelector(".totalHTML").innerHTML=productsHTML;

//problem is here://

const btn=document.querySelector(".addtocart");
console.log(btn);
btn.addEventListener("click",function(){
console.log("hello");
});

#There is no “hello” in console

this is my e-commerce project.

enter image description here

onclick of button addEventListener.console.log(“hello”) is not showing. i tried using advance function too.

i am trying to check if my click is working for further use of onclick to get the number(input) of <select> of html for cart Quantity.

and use that number to increase cartquantity and also use onclick to calculate the price .
so PLEASE help me and make the addeventlistener workable.

btn.addEventListener(“click”,()=>{

});

tetris – creating random block based on level

I have cloned a tetris game from github and I am trying to create a simple level block generator.

The difficulty of the generated level should inc with each stage/level.

I have never done something like this would be grateful if someone could help.

here is the code to system.js

//Peca atual que está descendo na matriz
let currentPiece = null;

//retorna um numero aleatorio para a peca
const randomBetween = (min, max) => {
    let x = Math.floor(Math.random() * (max - min + 1) + min);
    return x;
}

//Cria uma nova peca
//Todas as pecas do jogo TETRIS tem 4 blocos então o quinto elemento da matriz retorno é a cor da peca
//E o sexto (ultimo) elemento da matriz de retorno e o bloco de referencia para girar a peca
const renderPiece = (grid) => {
    //Meio da grid
    const middleColumn = Math.floor(grid[0].length/2);

    switch(randomBetween(0, 6)){
        case 0:
            return [[-2, middleColumn-1], [-2, middleColumn], [-1, middleColumn-1], [-1, middleColumn], 'blue', null] //[]
        case 1:
            return [[-2, middleColumn-1], [-2, middleColumn], [-2, middleColumn+1], [-1, middleColumn-1], 'red', 1] //L
        case 2:
            return [[-2, middleColumn-1], [-2, middleColumn], [-2, middleColumn+1], [-1, middleColumn+1], 'green', 1] //L - invertido
        case 3:
            return [[-1, middleColumn-1], [-1, middleColumn], [-2, middleColumn], [-2, middleColumn+1], 'pink', 1] //[]S
        case 4:
            return [[-2, middleColumn-1], [-2, middleColumn], [-1, middleColumn], [-1, middleColumn+1], 'brown', 1] //S - invertido
        case 5:
            return [[-2, middleColumn-1], [-2, middleColumn], [-2, middleColumn+1], [-1, middleColumn], 'yellow', 1] //T
        default:
            return [[-4, middleColumn], [-3, middleColumn], [-2, middleColumn], [-1, middleColumn], 'purple', 1] //I 
    }
}

const downPiece = (grid, dispatch) => {
    //copia o conteudo da variavel currentPiece
    let aux = [[],1,2,3];

    //Desce a peca virtual e retorna false se estiver na ultima posicao
    for(let i=0; i<4; i++){
        aux[i] = [];
        aux[i][0] = currentPiece[i][0];
        aux[i][1] = currentPiece[i][1];

        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = null;
        
        aux[i][0]++;

        if(aux[i][0] >= grid.length){
            for(let j=0; j<4; j++){
                grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
            }

            return false;
        }
    }

    aux[4] = currentPiece[4];
    aux[5] = currentPiece[5];

    //Se a peca virtual tiver uma posicao ocupada ou chegar ao fim da matriz, retorna falso
    for(let i=0; i<4; i++){
        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            if(grid[aux[i][0]][aux[i][1]]){
                
                for(let j=0; j<4; j++){
                    if(currentPiece[j][0] >= 0)
                        grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
                }

                if(aux[i][0] == 0){
                    dispatch({ type: "game-over" });
                }

                return false;
            }
    }

    //Se nao, copia o novo valor para a peca atual
    for(let i=0; i<4; i++){
        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = aux[4];
        
        currentPiece[i][0] = aux[i][0];
        currentPiece[i][1] = aux[i][1];
    }

    return true;
}

//Movimenta a peca para a esquerda ou direita
const moveLeftOrRight = (direction, grid) => {
    //Guarda a currentPiece em uma variavel usada como uma peca virtual
    let aux = [];

    //Verifica se a peca atual esta na borda da grid
    for(i=0; i<4; i++)
        if(direction == 1 && currentPiece[i][1] == grid[0].length-1)
            return;
        else if(direction == -1 && currentPiece[i][1] == 0)
            return;

    //Retira a peca atual da matriz para nao haver colisao com o bloco da propria peca atual
    for(let i=0; i<4; i++)
        if(currentPiece[i][0] >= 0)
            grid[currentPiece[i][0]][currentPiece[i][1]] = null;

    //Movimenta a peca virtual na horizontal
    for(let i=0; i<4; i++){
        aux[i] = [];

        aux[i][0] = currentPiece[i][0];
        aux[i][1] = currentPiece[i][1];

        aux[i][1]+=direction;
    }

    aux[4] = currentPiece[4];
    aux[5] = currentPiece[5];

    //Verifica se a posicao esta ocupada -> nao move a peca
    for(i=0; i<4; i++)
        if(aux[i][0] >= 0 && grid[aux[i][0]][aux[i][1]]){
            for(let j=0; j<4; j++)
                if(currentPiece[j][0] >= 0)
                    grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];

            return;
        }

    for(let i=0; i<4; i++){
        currentPiece[i][0] = aux[i][0];
        currentPiece[i][1] = aux[i][1];

        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = aux[4];
    }
}


//Rotaciona a peca que esta descendo utilizando um algoritmo de rotacao
const rotateCurrentPiece = (grid) => {
    let aux = [];

    //Retira a peca atual da matriz para nao haver colisao com o bloco da propria peca atual
    for(let i=0; i<4; i++)
        if(currentPiece[i][0] >= 0)
            grid[currentPiece[i][0]][currentPiece[i][1]] = null;

    for(let i=0; i<4; i++){
        aux[i] = [];

        aux[i][0] = currentPiece[i][0];
        aux[i][1] = currentPiece[i][1];
    }

    aux[4] = currentPiece[4];
    aux[5] = currentPiece[5];

    for(let i=0; i<4; i++){
        if(i != aux[5] && aux[5]){
            let newX = aux[i][1] + aux[1][0] - aux[1][1];
            let newY = aux[1][0] + aux[1][1] - aux[i][0];

            aux[i][0] = newX;
            aux[i][1] = newY;
        }

        if(aux[i][0] >= grid.length || aux[i][1] < 0 || aux[i][1] >= grid[0].length){
            for(let j=0; j<4; j++){
                if(currentPiece[j][0] >= 0)
                    grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
            }
            return;
        }
    }

    //Se a peca virtual tiver uma posicao ocupada ou em uma das bordas -> nao gira a peca
    for(let i=0; i<4; i++){
        if(aux[i][1] < 0 || aux[i][1] >= grid[0].length){
            for(let j=0; j<4; j++){
                if(currentPiece[j][0] >= 0)
                    grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
            }

            return;
        }

        if(aux[i][0] >= 0 && aux[i][0] < grid.length && aux[i][1] < grid[0].length && aux[i][1] >= 0){
            if(grid[aux[i][0]][aux[i][1]]){
                for(let j=0; j<4; j++){
                    if(currentPiece[j][0] >= 0)
                        grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
                }
    
                return;
            }
        }
    }

    //Se nao, copia o novo valor para a peca atual
    for(let i=0; i<4; i++){
        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = aux[4];
        
        currentPiece[i][0] = aux[i][0];
        currentPiece[i][1] = aux[i][1];
    }
}

export const GameLoop = (entities, { touches, dispatch, events }) => {
    //Matriz 
    let grid = entities.grid.grid;

    //Se nao existir uma peca atual, renderiza um nova peca
    currentPiece = (!currentPiece) ? renderPiece(grid) : currentPiece;
   //currentPiece = [[0, 5], [0, 6], [0, 7], [1, 5], "red", 1]
    //console.log(entities)

    //Eventos das pecas
    if (events.length){
        for(let i=0; i<events.length; i++){
            if (events[i].type === 'move-left'){
                moveLeftOrRight(-1, grid);
            }else if (events[i].type === 'move-right'){
                moveLeftOrRight(1, grid);
            }else if (events[i].type === 'rotate'){
                rotateCurrentPiece(grid);
            }else if(events[i].type === 'slide'){
                //Desce a peca ate retornar nulo
                while(downPiece(grid, dispatch));
            }
        }
    }

    //If para a velocidade do jogo
    entities.grid.nextMove -= 1;
    if (entities.grid.nextMove === 0){
        entities.grid.nextMove = entities.grid.updateFrequency;

        //Desliza uma peca na matriz
        //se o retorno for falso entao a peca atual passa a ser nula
        if(!downPiece(grid, dispatch)){
            currentPiece = null;

            let bonus = 0;

            for(let i=grid.length-1; i>=0; i--){
                if(grid[i].filter((value) => { return value === null }).length == 0){
                    grid.splice(i, 1);

                    let newLine = [];

                    for(let j=0; j<grid[0].length; j++)
                        newLine[j] = null;

                    grid.unshift(newLine);
                
                    i++;

                    dispatch({ type: "add-score", score: 100*(++bonus)});
                }
            }
        }
    }

    return entities;
};

tetris – creating random block base on level

I have cloned a tetris game from github and I am trying to create a simple level block generator.

The difficulty of the generated level should inc with each stage/level.

I have never done something like this would be grateful if someone could help.

here is the code to system.js

//Peca atual que está descendo na matriz
let currentPiece = null;

//retorna um numero aleatorio para a peca
const randomBetween = (min, max) => {
    let x = Math.floor(Math.random() * (max - min + 1) + min);
    return x;
}

//Cria uma nova peca
//Todas as pecas do jogo TETRIS tem 4 blocos então o quinto elemento da matriz retorno é a cor da peca
//E o sexto (ultimo) elemento da matriz de retorno e o bloco de referencia para girar a peca
const renderPiece = (grid) => {
    //Meio da grid
    const middleColumn = Math.floor(grid[0].length/2);

    switch(randomBetween(0, 6)){
        case 0:
            return [[-2, middleColumn-1], [-2, middleColumn], [-1, middleColumn-1], [-1, middleColumn], 'blue', null] //[]
        case 1:
            return [[-2, middleColumn-1], [-2, middleColumn], [-2, middleColumn+1], [-1, middleColumn-1], 'red', 1] //L
        case 2:
            return [[-2, middleColumn-1], [-2, middleColumn], [-2, middleColumn+1], [-1, middleColumn+1], 'green', 1] //L - invertido
        case 3:
            return [[-1, middleColumn-1], [-1, middleColumn], [-2, middleColumn], [-2, middleColumn+1], 'pink', 1] //[]S
        case 4:
            return [[-2, middleColumn-1], [-2, middleColumn], [-1, middleColumn], [-1, middleColumn+1], 'brown', 1] //S - invertido
        case 5:
            return [[-2, middleColumn-1], [-2, middleColumn], [-2, middleColumn+1], [-1, middleColumn], 'yellow', 1] //T
        default:
            return [[-4, middleColumn], [-3, middleColumn], [-2, middleColumn], [-1, middleColumn], 'purple', 1] //I 
    }
}

const downPiece = (grid, dispatch) => {
    //copia o conteudo da variavel currentPiece
    let aux = [[],1,2,3];

    //Desce a peca virtual e retorna false se estiver na ultima posicao
    for(let i=0; i<4; i++){
        aux[i] = [];
        aux[i][0] = currentPiece[i][0];
        aux[i][1] = currentPiece[i][1];

        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = null;
        
        aux[i][0]++;

        if(aux[i][0] >= grid.length){
            for(let j=0; j<4; j++){
                grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
            }

            return false;
        }
    }

    aux[4] = currentPiece[4];
    aux[5] = currentPiece[5];

    //Se a peca virtual tiver uma posicao ocupada ou chegar ao fim da matriz, retorna falso
    for(let i=0; i<4; i++){
        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            if(grid[aux[i][0]][aux[i][1]]){
                
                for(let j=0; j<4; j++){
                    if(currentPiece[j][0] >= 0)
                        grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
                }

                if(aux[i][0] == 0){
                    dispatch({ type: "game-over" });
                }

                return false;
            }
    }

    //Se nao, copia o novo valor para a peca atual
    for(let i=0; i<4; i++){
        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = aux[4];
        
        currentPiece[i][0] = aux[i][0];
        currentPiece[i][1] = aux[i][1];
    }

    return true;
}

//Movimenta a peca para a esquerda ou direita
const moveLeftOrRight = (direction, grid) => {
    //Guarda a currentPiece em uma variavel usada como uma peca virtual
    let aux = [];

    //Verifica se a peca atual esta na borda da grid
    for(i=0; i<4; i++)
        if(direction == 1 && currentPiece[i][1] == grid[0].length-1)
            return;
        else if(direction == -1 && currentPiece[i][1] == 0)
            return;

    //Retira a peca atual da matriz para nao haver colisao com o bloco da propria peca atual
    for(let i=0; i<4; i++)
        if(currentPiece[i][0] >= 0)
            grid[currentPiece[i][0]][currentPiece[i][1]] = null;

    //Movimenta a peca virtual na horizontal
    for(let i=0; i<4; i++){
        aux[i] = [];

        aux[i][0] = currentPiece[i][0];
        aux[i][1] = currentPiece[i][1];

        aux[i][1]+=direction;
    }

    aux[4] = currentPiece[4];
    aux[5] = currentPiece[5];

    //Verifica se a posicao esta ocupada -> nao move a peca
    for(i=0; i<4; i++)
        if(aux[i][0] >= 0 && grid[aux[i][0]][aux[i][1]]){
            for(let j=0; j<4; j++)
                if(currentPiece[j][0] >= 0)
                    grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];

            return;
        }

    for(let i=0; i<4; i++){
        currentPiece[i][0] = aux[i][0];
        currentPiece[i][1] = aux[i][1];

        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = aux[4];
    }
}


//Rotaciona a peca que esta descendo utilizando um algoritmo de rotacao
const rotateCurrentPiece = (grid) => {
    let aux = [];

    //Retira a peca atual da matriz para nao haver colisao com o bloco da propria peca atual
    for(let i=0; i<4; i++)
        if(currentPiece[i][0] >= 0)
            grid[currentPiece[i][0]][currentPiece[i][1]] = null;

    for(let i=0; i<4; i++){
        aux[i] = [];

        aux[i][0] = currentPiece[i][0];
        aux[i][1] = currentPiece[i][1];
    }

    aux[4] = currentPiece[4];
    aux[5] = currentPiece[5];

    for(let i=0; i<4; i++){
        if(i != aux[5] && aux[5]){
            let newX = aux[i][1] + aux[1][0] - aux[1][1];
            let newY = aux[1][0] + aux[1][1] - aux[i][0];

            aux[i][0] = newX;
            aux[i][1] = newY;
        }

        if(aux[i][0] >= grid.length || aux[i][1] < 0 || aux[i][1] >= grid[0].length){
            for(let j=0; j<4; j++){
                if(currentPiece[j][0] >= 0)
                    grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
            }
            return;
        }
    }

    //Se a peca virtual tiver uma posicao ocupada ou em uma das bordas -> nao gira a peca
    for(let i=0; i<4; i++){
        if(aux[i][1] < 0 || aux[i][1] >= grid[0].length){
            for(let j=0; j<4; j++){
                if(currentPiece[j][0] >= 0)
                    grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
            }

            return;
        }

        if(aux[i][0] >= 0 && aux[i][0] < grid.length && aux[i][1] < grid[0].length && aux[i][1] >= 0){
            if(grid[aux[i][0]][aux[i][1]]){
                for(let j=0; j<4; j++){
                    if(currentPiece[j][0] >= 0)
                        grid[currentPiece[j][0]][currentPiece[j][1]] = currentPiece[4];
                }
    
                return;
            }
        }
    }

    //Se nao, copia o novo valor para a peca atual
    for(let i=0; i<4; i++){
        if(aux[i][0] >= 0 && aux[i][0] < grid.length)
            grid[aux[i][0]][aux[i][1]] = aux[4];
        
        currentPiece[i][0] = aux[i][0];
        currentPiece[i][1] = aux[i][1];
    }
}

export const GameLoop = (entities, { touches, dispatch, events }) => {
    //Matriz 
    let grid = entities.grid.grid;

    //Se nao existir uma peca atual, renderiza um nova peca
    currentPiece = (!currentPiece) ? renderPiece(grid) : currentPiece;
   //currentPiece = [[0, 5], [0, 6], [0, 7], [1, 5], "red", 1]
    //console.log(entities)

    //Eventos das pecas
    if (events.length){
        for(let i=0; i<events.length; i++){
            if (events[i].type === 'move-left'){
                moveLeftOrRight(-1, grid);
            }else if (events[i].type === 'move-right'){
                moveLeftOrRight(1, grid);
            }else if (events[i].type === 'rotate'){
                rotateCurrentPiece(grid);
            }else if(events[i].type === 'slide'){
                //Desce a peca ate retornar nulo
                while(downPiece(grid, dispatch));
            }
        }
    }

    //If para a velocidade do jogo
    entities.grid.nextMove -= 1;
    if (entities.grid.nextMove === 0){
        entities.grid.nextMove = entities.grid.updateFrequency;

        //Desliza uma peca na matriz
        //se o retorno for falso entao a peca atual passa a ser nula
        if(!downPiece(grid, dispatch)){
            currentPiece = null;

            let bonus = 0;

            for(let i=grid.length-1; i>=0; i--){
                if(grid[i].filter((value) => { return value === null }).length == 0){
                    grid.splice(i, 1);

                    let newLine = [];

                    for(let j=0; j<grid[0].length; j++)
                        newLine[j] = null;

                    grid.unshift(newLine);
                
                    i++;

                    dispatch({ type: "add-score", score: 100*(++bonus)});
                }
            }
        }
    }

    return entities;
};