Javascript- struggling, especially with changing css classes attributes

Thanks to sites such as this, I have learned HTML, CSS, PHP and SQL to a fairly good standard. However, I am really struggling with Javascript.

In my specific case I have concluded that for my menu I would be better using tabs rather than dropdowns- I know that’s an ongoing debate, but for me, I have found this to be the best solution.

I learned about tabs from W3Schools and used their example to try and make every tab close when they lost focus, but I cannot find any way of doing so. For reference, I attach the bare bones example from W3Schools below (permitted as per their T&C). Be assured that I am not being lazy and I already understand how to convert this to PC/smartphone responsive (including hamburger menu) and will be populating the menu by database driven PHP/SQL- but it’s just “as is” here to avoid confusion.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {font-family: Arial;}

/* Style the tab */
.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

/* Style the buttons inside the tab */
.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}

/* Change background color of buttons on hover */
.tab button:hover {
  background-color: #ddd;
}

/* Create an active/current tablink class */
.tab button.active {
  background-color: #ccc;
}

/* Style the tab content */
.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}

/* Style the close button */
.topright {
  float: right;
  cursor: pointer;
  font-size: 28px;
}

.topright:hover {color: red;}
</style>
</head>
<body>

<h2>Tabs</h2>
<p>Click on the x button in the top right corner to close the current tab:</p>

<div class="tab">
  <button class="tablinks" onclick="openCity(event, 'London')" id="defaultOpen">London</button>
  <button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
  <button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>

<div id="London" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">&times</span>
  <h3>London</h3>
  <p>London is the capital city of England.</p>
</div>

<div id="Paris" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">&times</span>
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id="Tokyo" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">&times</span>
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

<script>
function openCity(evt, cityName) {
  var i, tabcontent, tablinks;
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  document.getElementById(cityName).style.display = "block";
  evt.currentTarget.className += " active";
}

// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
</script>
   
</body>
</html> 

I have tried this

<div id="London" class="tabcontent" onblur="style.display.visibility='none'">Lorem Ipsum....</div>

for each and many similar examples, but nothing seems to work.

I have also tried several ‘listening’ for onclick etc as described, but I can’t get any to work.

I can find 100s of people asking this or a similar question, but I just don’t understand what I need to copy or change for my example. What would really be helpful is not only the few lines of code that I know I am missing but someone adding “this bit here does this, that bit there does that…>” as that would help me understand.

Many thanks in advance. Apologies if I haven’t asked this question well- despite learning everything else in this last year, this is my first time asking on a forum.

Textarea – problems setting attribute

I’m saving the innerHTML of a div that contains several form inputs including textarea, select and textbox.

I’m setting the attributes for all elements using the onkeyup or onchange handler and the textbox and selected option get stored and returned but not the textarea. Setting the textarea attribute ie: ta.setattribute(‘value’,this.value) adds a new “value” attribute to the tag that stores the text but doesn’t populate the textarea. Also, when viewing the textarea in the console I don’t see any content in the textarea but do see the content in a value property.

<textarea id="ta" value="some text"></textarea>

Any idea how set the textarea attribute so it returns content to the textarea instead of creating and populating the value attribute? TIA.

What is the proper method of running scripts in the highest possible context level in web extensions?

I have been maintaining a utility userscript for a social media site for a few months now, and after a lot of promising user feedback I’m looking to make the jump to recreating it as a fully-fledged web extension.

However, one of the key features of the script and future extension involves running a hook function at document-start that defines custom getters and setters for a specific window property used by the website at runtime. My current script makes use of a rather convoluted method:

const main = () => {
  // hook function
};

const getNonce = () => {
  const { nonce } = [...document.scripts].find(script => script.nonce) || '';
  if (nonce === '') console.error('empty script nonce attribute: script may not inject');
  return nonce;
};

const script = () => { 
  const s = document.createElement("script");
  s.innerHTML = `const main = ${main.toString()}; main();`;
  s.nonce = getNonce();
  return s;
}

if (!document.head) {
  const newNodes = [];
  const findHead = () => {
    const nodes = newNodes.splice(0);
    if (nodes.length !== 0 && (nodes.some(node => node.matches('head') || node.querySelector('head') !== null))) {
      const head = nodes.find(node => node.matches('head'));
      head.append(script());
    }
  };
  const observer = new MutationObserver(mutations => {
    const nodes = mutations
      .flatMap(({ addedNodes }) => [...addedNodes])
      .filter(node => node instanceof Element)
      .filter(node => node.isConnected);
    newNodes.push(...nodes);
    findHead();
  });
  observer.observe(document.documentElement, { childList: true, subtree: true });
} else document.head.append(script);

While this works fine as for a userscript, and functions exactly the same when migrated to a web extension content script, it’s clear that there is certainly a better method with which to accomplish the same goal in a less…hacky manner. I’ve done a lot of digging through the MDN webExtension docs, but nothing I’ve come across so far has enlightened me as to what exactly this superior option may be.

how can I minimize the code or rewrite this smaller?

I think my code can be smaller but idk how can I minimize it ?

How you would rewrite the code smaller ?

PS:

I get a JSON object and I have to find the key name from an value.

I have to found which color has the option key

exp:

option1: "blue"
option2: "S"

but if I get another request then it could be like that:

option1: "S"
option2: "blue"

so it can be reversed, so I have to find the key name from an color name

const getKeyByValue = (obj: _Variant, value: string) => Object.keys(obj).find(key => obj[key] === value.toLowerCase());

let k = null;

for(let i = 0; i < variants.length; i++) {
    k = getKeyByValue(variants[i], "schwarz");
      if(k) {
          break;
      }
     k = getKeyByValue(variants[i], "black");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "weiß");
      if(k) {
          break;
      }
     k = getKeyByValue(variants[i], "white");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "rot");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "red");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "gelb");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "yellow");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "grün");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "green");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "blau");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "blue");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "lila");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "purple");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "beige");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "pink");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "camouflage");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "gold");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "silber");
      if(k) {
          break;
      }
    k = getKeyByValue(variants[i], "silver");
      if(k) {
          break;
      }

How to identify the company from the URL given?

The image is just for example. I have a use case where i have to identify the company based of URLs,
Lets say
amazon.com —> amazon —> amazon logo

amzn.to —> amazon —> amazon logo

yotube.com —> youtube —> youtube logo

youtu.be —> youtube —> youtube logo

thats it, now is there any library? and API? or any trick to identify diffeent formats of URL instaed of manyually setting it one by one?

I have tried manually giving an array of key and values , where key is youtube and value is the domain format youtube uses, it’s not reliable.

tried to find some API that will help but didn’t find any

Javascript extract value from key-value pair in object

I’m getting the following data returned from an API:

{
    "statusCode": 200,
    "successful": true,
    "userPreferences": [
        {
            "category": "Alerts",
            "preference": {
                "ContentViolations": "true",
                "UserCommentsYou": "true",
                "UserMessagesYou": "true"
            }
        },
        {
            "category": "Display",
            "preference": {
                "DateFormat": "mm-dd-yyyy",
                "TimeFormat": "12-hour"
            }
        },
        {
            "category": "EmailList",
            "preference": {
                "ReceiveDailyDigest": "true",
                "ReceiveDealsOffers": "true"
            }
        },
        {
            "category": "Privacy",
            "preference": {
                "OtherUsersMessageYou": "true",
                "OtherUsersViewProfile": "true"
            }
        },
        {
            "category": "Units",
            "preference": {
                "Measurement": "inches",
                "Weight": "pounds"
            }
        }
    ]
}

I need to extract a preference value from a key value pair. Here is what I have:

const result = userPreferences?.filter(x => x.category === "Alerts" && x.preference["UserMessagesYou"]).map(x => x.preference.value);

It’s returning string[] | undefined but I would like it to retutn string.

In the example above I would like result to have the value “true”.

Mapbox fit markers with clusters

I’m trying to work out how to automatically zoom / fly to a group of markers on a map loaded via a geojson file, but with clustering.

I have my map, markers and clustering working with the example code from Mapbox.

However I can’t work out how to create an array of coordinates from the geojson source so I can run fitBounds.

const map = new mapboxgl.Map({
container: 'map',
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio
style: 'mapbox://styles/mapbox/dark-v11',
center: [-103.5917, 40.6699],
zoom: 3
});
 
map.on('load', () => {
// Add a new source from our GeoJSON data and
// set the 'cluster' option to true. GL-JS will
// add the point_count property to your source data.
map.addSource('earthquakes', {
type: 'geojson',
// Point to GeoJSON data. This example visualizes all M1.0+ earthquakes
// from 12/22/15 to 1/21/16 as logged by USGS' Earthquake hazards program.
data: 'https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson',
cluster: true,
clusterMaxZoom: 14, // Max zoom to cluster points on
clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
});
 
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'earthquakes',
filter: ['has', 'point_count'],
paint: {
// Use step expressions (https://docs.mapbox.com/style-spec/reference/expressions/#step)
// with three steps to implement three types of circles:
//   * Blue, 20px circles when point count is less than 100
//   * Yellow, 30px circles when point count is between 100 and 750
//   * Pink, 40px circles when point count is greater than or equal to 750
'circle-color': [
'step',
['get', 'point_count'],
'#51bbd6',
100,
'#f1f075',
750,
'#f28cb1'
],
'circle-radius': [
'step',
['get', 'point_count'],
20,
100,
30,
750,
40
]
}
});
 
map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'earthquakes',
filter: ['has', 'point_count'],
layout: {
'text-field': ['get', 'point_count_abbreviated'],
'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
'text-size': 12
}
});
 
map.addLayer({
id: 'unclustered-point',
type: 'circle',
source: 'earthquakes',
filter: ['!', ['has', 'point_count']],
paint: {
'circle-color': '#11b4da',
'circle-radius': 4,
'circle-stroke-width': 1,
'circle-stroke-color': '#fff'
}
});

I would imagine this is a fairly common requirement and should really have an example of its own.

How can I obtain the area of a pothole using a React Native app for Android?

I’m developing an application using React Native for Android, and I need assistance in implementing a feature that calculates the area of a pothole from a photograph. For instance, I have a pothole on the asphalt and I want to take a picture to measure its dimensions and derive the corresponding area. Could someone guide me on how to approach this issue within the application

How to convert the data sys.sunset of the API (https://openweathermap.org/current) to the correct value to use into new Date(sys.sunset) JavaScript?

I am trying to display the date and time of sunset from another city different from where I am. When I make the call and print it the response is Tue Jan 20 1970 11:45:01

The API documentation says that the format of sys.sunset is unix, UTC; however, I must convert it to milliseconds to be accepted by Date.UTC(). Additionally, I should add or subtract the time according to the time zone in which the client is.

let date = new Date(DATA.sys.sunset);

date.toISOString();

console.log(date);

How to put focus() cursor behind text

I am working with React and need help with useRef hook concrete with focus() javascript function.
Everything work fine but there is small fault. I want after click on edit button focus cursor on textarea. Cursor focus but it is on start of the line. I want blink cursor behind text, so that I can immediately continue writing and editing the text.

  useEffect(() => {
    if (!isEdit) {
      refUpdate.current.focus()
    }
  }, [isEdit])

  

<textarea
        type="text"
        className="update-textarea"
        value={value}
        ref={refUpdate}
        onChange={(e) => setValue(e.target.value)}
      />

After that focus work, but blink at the start of text line. My goal is put cursor behind edited text.
Thanks.

Difference between destructuring in function vs React component

I am experiencing a very frustrating issue with regards to object destructuring in my function parameters. I have the following code in one of my components:

import React from "react";
import { range } from "../../utils";
import { checkGuess } from "../../game-helpers";

function Guess({ guess, answer }) {
  const guessEmpty = guess === undefined ? true : false;
  const letters = !guessEmpty && checkGuess(guess.value, answer);

  function renderLetter({ letter = undefined, status = undefined } = {}, num) {
    return (
      <span className={`cell ${status}`} key={num}>
        {letter}
      </span>
    );
  }

  return (
    <>
      {
        <p className="guess">
          {range(5).map((num) => renderLetter(letters[num], num))}
        </p>
      }
    </>
  );
}

export default Guess;

The letters constant is an array, which will either be set to false or consist of a list of objects depending on whether the guess input parameter for the Guess function is empty or not.

When I pass letters[num] (which can be an object, or undefined) into my renderLetter function, my letter and status input parameters are either converted to undefined or strings depending on the input through object destructuring. This all works great.

However, instead of rendering the <span> elements by using the renderLetter function, I now want to move this to a new component. The code for this component is:

import React from "react";

function Letter({ letter = undefined, status = undefined } = {}) {
  return (
    <>
      <span className={`cell ${status}`}>{letter}</span>
    </>
  );
}

export default Letter;

Similarly to the way I called the renderLetter function, I am now attempting to render the components:

return (
    <>
      {
        <p className="guess">
          {range(5).map((num) => (
            <Letter letter={letters[num]} num={num} />
          ))}
        </p>
      }
    </>
  );
}

However, when logging letter and status parameters inside the Letter component, the letter parameter returns an object, and the status parameter returns undefined. As such, I’m assuming I’m messing up in destructuring the input correctly.

I fail to see why however, since doing it this exact same way does work when using a function inside the same component, while it does not when transferring the code to a separate component.

Any help in figuring this out would be greatly appreciated!

Express Static Middleware will not be created

I want to pack my remix app on an express server so that I can host it. The problem is that express does not create the static middlewares and I get errors because the remix app needs them.

I have already looked but have not yet found a solution that applies to my problem. I have already checked the ports and looked at which routes it creates.

express:

import { createRequestHandler } from "@remix-run/express";
import express from "express";

// notice that the result of `remix build` is "just a module"
import * as build from "./build/index.js";
import { broadcastDevReady } from "@remix-run/node";

const app = express();
app.use("/", express.static("public"));



// and your app is "just a request handler"
app.all("*", createRequestHandler({ build }));


app.listen(8000, () => {
  console.log("App listening on http://localhost:8000");

  if (process.env.NODE_ENV === "development") {
    broadcastDevReady(build);
  }
});

const routes = [];
app._router.stack.forEach((middleware) => {
  if (middleware.route) {
    // Routen, die direkt in der App definiert sind
    routes.push(middleware.route.path);
  } else if (middleware.name === 'router') {
    // Routen, die durch einen Router erstellt wurden
    middleware.handle.stack.forEach((handler) => {
      if (handler.route) {
        routes.push(handler.route.path);
      }
    });
  }
});

// Ausgabe der gefundenen Routen
console.log('Verfügbare Routen:', routes);

Files

I would like all files from the public folder and build folder to be available as middleware.

Does anyone have an idea why this is not working and perhaps a solution?

Why is the terminal in an infinite loop with the prompts?

In relation to my previous question:
Why is Node.js throwing an error to my require() statement?

I added type: module to my packages.json and the code works and asks the questions. However, it keep asking the questions instead of stopping at the last question and replacing the placeholders.

#!/usr/bin/env node

import { program } from 'commander';
import { execa } from 'execa';
import inquirer from 'inquirer';
import fs from 'fs';
import path from 'path';

program
  .command('make-plugin <folder-name>')
  .description('Clone repo and change values')
  .action(async (folderName) => {
    const repoURL = 'https://github.com/jb1995coder/boilerplate.git';
    const targetFolder = path.resolve(process.cwd(), folderName);

    // Clone the repository
    await execa('git', ['clone', repoURL, folderName]);

    // Enumerate through files and replace placeholders
    const files = fs.readdirSync(targetFolder);
    const questions = [
      // Questions being asked
    ];

    for (const file of files) {
      const filePath = path.join(targetFolder, file);
      let content = fs.readFileSync(filePath, 'utf-8');

      // Replace placeholders in the content
      const answers = await inquirer.prompt(questions);
      for (const key in answers) {
        const placeholder = `{{${key}}}`;
        const replacement = answers[key];
        content = content.replace(new RegExp(placeholder, 'g'), replacement);
      }

      // Update PHP file name
      if (file === 'plugin-boilerplate.php') {
        const newPhpFileName = `${answers['plugin_slug']}.php`;
        const newPhpFilePath = path.join(targetFolder, newPhpFileName);
        fs.renameSync(filePath, newPhpFilePath);
      }

      // Write back to the file
      fs.writeFileSync(filePath, content, 'utf-8');
    }

    console.log('Plugin boilerplate was made successfully! Happy coding! :D');
  });

program.parse(process.argv);

Allowing customers to edit their order in my account Woocommerce

I’ve been doing a lot of research regarding this issue and still can’t process it, would someone be willing to help friend developer for this? I just need pointers on how and where.

I need to customize my account orders tab so a customer can edit his order if it’s on awaiting payment or on hold or whatevere the status it is exept of course paid or completed.

Customer must be able to add, remove or change quantity of products in order, change billing/shipping fields ( some custom fields on it along the line ). I do not want plugin based solution since i want to build it from scratch.

All advices and feedback is welcomed and much appreciated. Thank you

I have tried multiple things i could find on internet regarding this but most of them are for admins to edit and there is bloomberg post but that’s cancelling order and going thru checkout phase all over again to create a new one, i would like to keep it in the my account.

problem with typescript it doesn’t let me put the prop in react and zustand

interface ArticuloCompra {
  id: string;
  cantidad: number;
  titulo: string;
  precio: number;
  descuento: number;
  descripcion: string;
  imagen: string;
}

const enviarComprasUsuarios = ({
  grupos,
}: {
  grupos: { [key: string]: ArticuloCompra & { cantidad: number } };
}) => {
  // Assuming "usuario" and "precioTotal" are defined somewhere
  if (usuario.dinero >= precioTotal) {
    Object.values(grupos).forEach(
      (itemCompras: ArticuloCompra & { cantidad: number }) => {
        const { item, cantidad } = itemCompras;
        const { id } = item;
        const nuevoDinero = usuario.dinero - precioTotal * cantidad;

        console.log(id);

        // Adjust this line according to your store structure
        agregarComprasUsuarios(usuario.id, item);
        quitarArticulo(id); // Uncomment this line if needed
        setNDinero(nuevoDinero);
        actualizarDineroUsuario(usuario.id, nuevoDinero);
        rutaNavegacion("/compras/comprasCompradas/");
      }
    );
  }
};

in const { item } = itemCompras; it gives me this error:

Property 'item' does not exist on type 'ArticuloCompra & { cantidad: number; }'.ts(2339)

this is the store:

export interface ArticuloCompra {
  readonly id: string;
  cantidad: number;
  titulo: string;
  precio: number;
  descuento: number;
  descripcion: string;
  imagen: string;
}

export interface Usuarios {
  readonly id: string;
  usuario: string;
  contraseña: string;
  dinero: number;
  imagen: string;
  edad: number;
  articulosComprados: ArticuloCompra[];
}

interface DatosUsuarios {
  usuarios: Usuarios[];
  agregarComprasUsuarios: (usuarioId: string, item: ArticuloCompra) => void;
  actualizarDineroUsuario: (usuarioId: string, nuevoDinero: number) => void;
}

export const usuariosDatos = create<DatosUsuarios>((set) => ({
  usuarios: [
    {
      id: nanoid(),
      usuario: "hernan",
      contraseña: "mariela123",
      dinero: 300000000,
      edad: 23,
      articulosComprados: [],
      imagen: imagenHernan,
    },
  ],
  agregarComprasUsuarios: (usuarioId, item) =>
    set((state) => {
      const usuariosActualizados = state.usuarios.map((usuario) =>
        usuario.id === usuarioId
          ? {
              ...usuario,
              articulosComprados: [...usuario.articulosComprados, item],
            }
          : usuario
      );
      return { usuarios: usuariosActualizados };
    }),
  actualizarDineroUsuario: (usuarioId, nuevoDinero) =>
    set((state) => {
      const usuariosActualizados = state.usuarios.map((usuario) =>
        usuario.id === usuarioId ? { ...usuario, dinero: nuevoDinero } : usuario
      );
      return { usuarios: usuariosActualizados };
    }),
}));

These are the data that the item contains:

cantidad    : 1
descripcion : "Lorem ipsum dolor sit amet,"
descuento   : 30
id          : "dJt9GJt8_z92X9xbclVoY"
imagen      : "/src/assets/imagenes/pantalones/pantalon_verde.jpg"
precio      : 20000
titulo      : "pantalon verde"

I need to be able to pass the correct props to item to be able to correct the error:

Property 'item' does not exist on type 'ArticuloCompra & { cantidad: number; }'.ts(2339)
⚠ Error (TS2339)  | 
`Property item does not exist on type ArticuloCompra & {cantidad: number}
 .
const item: any