how to use hooks like useLocation with @react-router/fs-routes

I have a react app using react-router / nx / vite. When I setup the project, I choose ssr: true, and I now have the following

react-router.config.ts

import type { Config } from "@react-router/dev/config";

export default {
  ssr: true,
} satisfies Config;

routes.tsx

import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes() satisfies RouteConfig;

root.tsx

import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
  type MetaFunction,
  type LinksFunction,
} from 'react-router';

import '../styles.css';
import EntryCommon from './entry.common';

export const meta: MetaFunction = () => [
  {
    title: 'New Nx React Router App',
  },
];

export const links: LinksFunction = () => [
  { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
  {
    rel: 'preconnect',
    href: 'https://fonts.gstatic.com',
    crossOrigin: 'anonymous',
  },
  {
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
  },
];

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <EntryCommon>{children}</EntryCommon>
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

export default function App() {
  return <Outlet />;
}

Now, the issue I face is, when, inside a route in my apps/routes/ folder (for exemple the default _index.ts), I use a hook like useLocation or useNavigate my app will not work and return an error

chunk-KNED5TY2.mjs:188
Uncaught Error: useNavigate() may be used only in the context of a component.

But I dont get why would I need to wrap around a Router since I use route file convention.

What is the correct setup ?

Thank you

React useEffect, DOM, mount, rendering [duplicate]

I’m currently learning React and I don’t understand what the above concepts mean

useEffect(function, deps)

useEffect (() => {
  console.log('mout')
}, []);


useEffect (() => {
  console.log('rendering')
});

useEffect (() =>{
  console.log(name);
  console.log("update");
}[name]);

useEffect (() => {
  console.log('rendering')
  return () =>{
    console.log("what the");
  }
});
useEffect (() => {
  console.log('rendering')
  return () =>{
    console.log("what the");
  }
}[]);

useEffect (() => {
  console.log('rendering')
  return () =>{
    console.log("what the");
  }
}[name, age <- ????]);

The five concepts above are all different, so it’s hard to understand what’s going on.
Even if I ask gpt, I can’t understand because I don’t have the basic concepts.

How to resolve React hydration mismatch error to render third party data dumped from script tag?

The following third-party code is written in the CK editor in drupal in source mode:

    <script>
    window.page = 'gidd';
    </script><!-- On new release, please update the bundle count so that cache is busted --><!-- Add react-website-component script and styles here -->
 <script defer="" src="https://release-website-components.idmcdb.org/js/runtime.bundle.js?bundle=3"></script>
<script defer="" src="https://release-website-components.idmcdb.org/js/main.bundle.js?bundle=3"></script>
<link href="https://release-website-components.idmcdb.org/css/main.css?bundle=3" rel="stylesheet"><!-- end -->

Now, in the following React component (DatabasePage), we’re showing the third party data, that is rendering fine in frontend:

import { graphql } from "gatsby";
import React from "react";
import { Col, Container, Row } from "react-bootstrap";
import ExtractRichText from "../../molecules/ExtractRichText";
import "./database.scss";
import Seo from "../../atoms/seo";

const DatabasePage = ({ data }) => {
  return (
    <>
      <Container className="database-container">
        <Row>
          <Col>
            {/* <ExtractRichText
              richText={data?.nodeDatabasePage?.body?.value}
            ></ExtractRichText> */}
            <div
              dangerouslySetInnerHTML={{
                __html: data.nodeDatabasePage.body.value,
              }}
            />
          </Col>
        </Row>
      </Container>
    </>
  );
};

export default DatabasePage;

export const pageQuery = graphql`
  query ($id: String!) {
    nodeDatabasePage(id: { eq: $id }) {
      title
      body {
        value
      }
      field_meta_tags {
        description
        keywords
      }
      path {
        alias
      }
      relationships {
        field_metatag_image {
          url
        }
      }
    }
  }
`;

export const Head = ({ data }) => (
  <Seo
    title={data?.nodeDatabasePage?.title}
    image={data?.nodeDatabasePage?.relationships?.field_metatag_image?.url}
    description={data?.nodeDatabasePage?.field_meta_tags?.description}
    keywords={data?.nodeDatabasePage?.field_meta_tags?.keywords}
    url={data?.nodeDatabasePage?.path?.alias}
  />
);

Now we’ve modified the above component to the following:

import { graphql } from "gatsby";
import React from "react";
import { Col, Container, Row } from "react-bootstrap";
import ExtractRichText from "../../molecules/ExtractRichText";
import "./database.scss";
import Seo from "../../atoms/seo";

const DatabasePage = ({ data }) => {
  return (
    <>
      <Container className="database-container">
        <Row>
          <Col>
            <ExtractRichText
              richText={data?.nodeDatabasePage?.body?.value}
            ></ExtractRichText>
          </Col>
        </Row>
      </Container>
    </>
  );
};

export default DatabasePage;

export const pageQuery = graphql`
  query ($id: String!) {
    nodeDatabasePage(id: { eq: $id }) {
      title
      body {
        value
      }
      field_meta_tags {
        description
        keywords
      }
      path {
        alias
      }
      relationships {
        field_metatag_image {
          url
        }
      }
    }
  }
`;

export const Head = ({ data }) => (
  <Seo
    title={data?.nodeDatabasePage?.title}
    image={data?.nodeDatabasePage?.relationships?.field_metatag_image?.url}
    description={data?.nodeDatabasePage?.field_meta_tags?.description}
    keywords={data?.nodeDatabasePage?.field_meta_tags?.keywords}
    url={data?.nodeDatabasePage?.path?.alias}
  />
);

We’ve used ExtractRichText component, that’s handing parsing the code and render in the frontend.

Now the ExtractRichText component looks like following:

import * as React from "react";
import parse from "html-react-parser";
import { useFileFile } from "../../hooks/useFileFile";
import { useMediaFileFile } from "../../hooks/useMediaFileFile";
import "./extractRichText.scss"
export const ExtractRichText = ({ richText, extraClasses }) => {
  const drupalIDs = useFileFile().map((e) => e?.node?.drupal_id);
  const allFiles = useFileFile().map((e) => e?.node);
  const allMediafiles = useMediaFileFile().map((e) => e?.node);
  let body = "";
  if (richText) {
    body = extractImage(drupalIDs, richText, extraClasses, allFiles, allMediafiles);
  }
  return <div className={`rich-text ${extraClasses}`}>{body}</div>;
};
function extractImage(drupalIDs, body, extraClasses, allFiles, allMediafiles) {
  return parse(body, {
    transform: (node) => {
      if (node.type === "img" || node.type === "drupal-entity" || node.type === "drupal-media") {
        const currentFile = allFiles.find((file) => node.props["data-entity-uuid"] === file?.drupal_id);
        let imageUrl = currentFile?.publicUrl;
        let mediaUrl;
        let alt;
        if (node.type === "drupal-media") {
          const currentMedia = allMediafiles.find((media) => node.props["data-entity-uuid"] === media?.drupal_id);
          mediaUrl = currentMedia?.relationships?.field_media_image?.publicUrl;
          alt = currentMedia?.field_media_image?.alt;
        }
        const imgAlign = node.props["data-align"] || "";
        const height = node.props["height"];
        const width = node.props["width"];
        let src = imageUrl || mediaUrl || node.props["src"];
        if (src === node.props["src"]) {
          const isRelative = !/^https?:///i.test(src);
          if (isRelative) {
            const base = process.env.GATSBY_DRUPAL_URL.replace(//+$/, '');
            const path = src.replace(/^/+/, '');
            src = `${base}/${path}`;
          }
        }
        const imgStyles = {};
        if (width) {
          imgStyles.width = `${width}px !important`;
        } else {
          // imgStyles.width = `100%`;
        }
        if (height) {
          imgStyles.height = `auto`;
        } else {
          // imgStyles.height = `100%`;
        }
        return (
          <span className={`imgAlign-${imgAlign}`}>
            <img
              style={imgStyles}
              loading="lazy"
              className={`${extraClasses ?? ''} ${node?.type == 'drupal-media' ? 'w-100' : ''}`}
              alt={node?.props?.alt || alt || "image"}
              src={`${src}`}
            />
          </span>
        );
      }
      if (node.type === 'a' && node.props["data-entity-type"] === 'file') {
        const currentFile = allFiles.find((file) => node.props["data-entity-uuid"] === file?.drupal_id);
        const href = node.props["href"] || "";
        const fallbackImage = process.env.GATSBY_DRUPAL_URL + href;
        return (
          <a
            href={`${currentFile?.url || fallbackImage}`}
            target={`${node.props["target"] || ""}`}
            class={`${node.props["className"] || ""}`}
            aria-label={`${node.props['aria-label'] || ""}`}
            id={`${node.props["id"] || ""}`}
            rel={`${node.props["rel"] || ""}`}
          >{`${node.props["children"] || "Link"}`}</a>
        );
      }
      return node;
    },
  });
}
export default ExtractRichText;

But, after using ExtractRichText in DatabasePage component, we’re getting the following runtime errors and third party data are not showing as well:

throw new Error('Text content does not match server-rendered HTML.');
throw new Error('Hydration failed because the initial UI does not match what was ' + 'rendered on the server.');
var recoverableError = createCapturedValueAtFiber(new Error('There was an error while hydrating. Because the error happened outside ' + 'of a Suspense boundary, the entire root will switch to ' + 'client rendering.'), workInProgress); 

My assumption:
This happens because the HTML generated on the server (SSR) differs from what the client renders during hydration, and React throws a hydration error when it can’t reconcile them.

Conext: We’re dumping third-party code is written in the CK editor in
drupal in source mode.

How to fix these above errors and ensure that third-party data is rendering fine in front end?

performance language and framework [closed]

What is the best programming language and framework in the future list? I want to know that very much, Curiosity.

I hope I got the best solution in here that’s perfect and right information.
Many places and resources try it, but I think it is not perfect. Finally, I realized that I could ask a question for Stack Overflow developer team.

Error importing lodash in components when using Histoire

I’m using lodash for a number of things, and all works well. That is, until I try to write stories in Histoire. Everything works, except for lodash. Anytime a component uses lodash, I get one of two errors, depending on how I try to import

import cloneDeep from 'lodash/cloneDeep':

“The requested modules ‘xxxxx/lodash/cloneDeep.js’ does not provide an
export named ‘default'”

import { cloneDeep } from 'lodash':

The requested module ‘xxxxx/lodash/lodash.js’ does not provide an export named ‘clondeDeep'”

What is it about lodash that Histoire doesn’t like, and how do I get around it?

Why do I keep getting invalid email from my input field? EmailJS

I am currently developing an e-portfolio website while building and reaching the final steps for the website I have run into a problem with my input field section where I am giving employers a chance to connect with me through the website. However, as I have coded it I keep getting an “invalid email” popup but I am not sure as to why. Below I have provided a snippet of the code, as well as a screenshot of the invalid email error message, albeit with my actual email address marked out.enter image description here

import { useState, useEffect } from "react"
import "./style.css"
import BackgroundLines from "../BackgroundLines"
import ParaWriting from "../ParaWriting"
import { motion, useAnimation } from "framer-motion"
import ArrowUpRightIcon from "../../assets/Icon/arrow-up-right.svg"
import { useInView } from "react-intersection-observer"
import Button from "../Button"
import Time from "../Time"

// emailjs
import emailjs from "@emailjs/browser"

// JSON
import emailjsconfig from "../../constants/emailjs.json"
import Alert from "../Alert"

export default function Footer() {
  const controls = useAnimation()
  const [ref, inView] = useInView()
  const [isSending, setIsSending] = useState(false)
  const [sendStatus, setSendStatus] = useState({ processed: false, message: "", variant: "success" })
  const [hasAnimated, setHasAnimated] = useState(false)
  const [fieldValues, setFieldValues] = useState({
    name: false,
    email: false,
    message: false,
  })  

  const handleComplete = () => {
    setHasAnimated(true)
  }

  useEffect(() => {
    // Start animation when the component is in view
    if (inView && !hasAnimated) {
      controls.start("visible")
    }
  }, [inView, controls])

  const opacityVariant = {
    hidden: { opacity: 0 },
    visible: { opacity: 1 },
  }

  const inputFieldLineVariant = {
    hidden: { width: "0%" },
    visible: {
      width: "100%",
    },
  }

  const inputFields = [
    {
      label: "Name",
      type: "text",
      id: "name",
      placeholder: "Enter name",
      stateKey: "name",
    },
    {
      label: "Email",
      type: "email",
      id: "email",
      placeholder: "[email protected]",
      stateKey: "email",
    },
    {
      label: "Message",
      type: "textarea",
      id: "message",
      placeholder: "Your message",
      rows: "8",
      wrap: "soft",
      stateKey: "message",
    },
  ]

  const handleInputClick = (stateKey) => {
    setFieldValues({
      ...fieldValues,
      [stateKey]: true,
    })
  }

  const timeoutAlert = () =>
    setTimeout(() => {
      setSendStatus({ ...sendStatus, processed: false })
    }, 5000)

  const sendEmail = async () => {
    const requiredFields = ["name", "email", "message"]
    const missingFields = requiredFields.filter((field) => !fieldValues[field])

    if (missingFields.length > 0) {
      setSendStatus({ processed: true, variant: "error", message: "Not all fields were filled" })
      timeoutAlert()
      return
    }

    const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/
    if (!emailRegex.test(fieldValues.email)) {
      setSendStatus({ processed: true, variant: "error", message: "Invalid email" })
      return
    }

    setIsSending(true)
    try {
      const { serviceId, templateid, publicKey } = emailjsconfig

      console.log("trigger")

      const templateParams = {
        name: fieldValues.name,
        email: fieldValues.email,
        message: fieldValues.message,
      }

      const response = await emailjs.send(serviceId, templateid, templateParams, publicKey)

      console.log("Email sent successfully:", response)
      setIsSending(false)
      setSendStatus({ processed: true, variant: "success", message: "Success!" })
    } catch (error) {
      console.error("Error sending email:", error)
      setIsSending(false)
      setSendStatus({ processed: true, variant: "error", message: "Error" })
    }

    timeoutAlert()
  }

  return (
    <footer ref={ref} className="footer" id="contact">
      <BackgroundLines />

      <div className="footer--grid">
        <div className="footer--grid--heading">
          <h2>
            <ParaWriting stagger={0.08} text={"Get in "} sec={"touch"} />
          </h2>
        </div>
        <div className="footer--grid--form">
          {inputFields.map((field, index) => (
            <motion.div key={index} initial="hidden" animate={controls} variants={opacityVariant} transition={{ duration: 1, delay: 0.5 * (index + 1) }} className="input--div">
              <label htmlFor={field.id}>{field.label}</label>
              {field.type === "textarea" ? <textarea name={field.id} id={field.id} placeholder={field.placeholder} rows={field.rows} wrap={field.wrap} onFocus={() => handleInputClick(field.stateKey)}></textarea> : <input type={field.type} name={field.id} id={field.id} placeholder={field.placeholder} onClick={() => handleInputClick(field.stateKey)} />}
              <motion.div
                initial="hidden"
                animate={controls}
                variants={inputFieldLineVariant}
                transition={{
                  type: "spring",
                  stiffness: 20,
                  duration: 1,
                  delay: 0.5 * (index + 1),
                }}
                className="input--div--line"
              >
                <motion.div
                  initial="hidden"
                  animate={fieldValues[field.stateKey] && "visible"}
                  variants={inputFieldLineVariant}
                  transition={{
                    type: "spring",
                    stiffness: 20,
                    duration: 1,
                  }}
                ></motion.div>
              </motion.div>
            </motion.div>
          ))}
          <motion.div initial="hidden" animate={controls} variants={opacityVariant} transition={{ duration: 1, delay: 2 }} className="footer--grid--form--btn">
            <Button label={`${isSending ? "Sending it through" : "SEND MESSAGE"}`} icon={ArrowUpRightIcon} onClick={sendEmail} />
          </motion.div>
        </div>
      </div>

      <motion.div initial="hidden" animate={controls} variants={opacityVariant} transition={{ duration: 1, delay: 2.5 }} className="footer--bottom" onAnimationComplete={() => handleComplete()}>
        <p>Copyright © {new Date().getFullYear()} Cameron Watkins</p>
        <p>
          <Time delay={3} />
        </p>
        <p></p>
      </motion.div>
      <Alert isVisible={sendStatus.processed} text={sendStatus.message} variant={sendStatus.variant} />
    </footer>
  )
}

If any additional information is needed I’m more than happy to supply the GitHub repo, thanks in advance.

QML DoubleTap Handler firing twice?

I have a QML object called Vertex that gets created dynamically in a Repeater on a Canvas. It’s essentially a rectangle with some event functions on it. On a doubleTap, I want the doubleTap handler to call a function in the Canvas. But what’s happening is that the function seems to be getting called twice — once with the right parameters and once with some sketchy parameters.

Here’s the tapHandler code in Vertex.qml

TapHandler {
    onTapped: {
        selected = !selected;
    }
    onDoubleTapped: {
        console.log("Double click on "+tag);
        parent.parent.interceptDoubleClick(parent);
    }
}

Here’s the code that gets called in main.qml.

            function interceptDoubleClick(myVert) {
                console.log("intercepted!    Passed "+myVert.tag);
                console.log("myVert is "+myVert);
            }

Here’s the output.

qml: Double click on v2
qml: intercepted!    Passed v2
qml: myVert is Vertex_QMLTYPE_1(0x600001e9c0e0)
qml: Double click on 
qml: intercepted!    Passed 
qml: myVert is Vertex_QMLTYPE_1(0x600001ebcc40)

Note that the first time through, it correctly passes itself, and in the main.qml file I can query myVert.tag and get the correct value from tag. But then it fires again, and it seems to pass another Vertex object, but it is different and doesn’t have anything stored in myVert.tag.

Why is this firing twice (and where’s that second Vertex object coming from)?

Thanks,
bc

I’m working on a website, and I have an image carousel, but the timed intervals aren’t working. Does anyone know how I could make it work?

This is all of the code I have so far:

    <html> 
<head>
    <script src="script.js"></script>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title> UNTITLEDWEB.SITE </title>
</head>
<body> 
 <section class="container">
        <div class="slider-wrapper">
            <div class="slider">
                <img id="slide-1" src="4-Large.webp">
                <img id="slide-2" src="large.jpg">
                <img id="slide-3" src="DeepSixDrone_1.jpeg">
            </div>
            <div class="slider-nav">
                <a href="#slide-1"></a>
                <a href="#slide-2"></a>
                <a href="#slide-3"></a>
            </div>
        </div>
    </section>
</body>

here’s the css
how do I give the slides 5 second intervals?
I’m just going to put some random words here because it says I need more.

.container {
padding: 0rem;
}
.slider-wrapper {
position: relative;
max-width: auto;
margin: 0 auto;
}
.slider {
display: flex;
aspect-ratio: 16 / 6.5;
overflow-x: hidden;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
box-shadow: 0 1.5rem 3rem -0.75rem #00000036;
}
.slider img {
flex: 1 0 100%;
scroll-snap-align: start;
object-fit: cover;
}
.slider-nav {
display: flex;
column-gap: 1rem;
position: absolute;
bottom: 1.25rem;
left: 50%;
transform: translateX(-50%);
z-index: 1;
}
.slider-nav a {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
background-color: #fff;
opacity: 0.75;
transition: opacity ease 250ms;
}
.slider-nav a:hover {
opacity: 1;

that’s all the code I have. I’ve tried a lot of different things to get the intervals to work, but nothing has worked so far.

that is all

Is there a way to assign a WooCommerce $product SKU a class id (for a copy to clipboard button)?

First, I want to say that I’m brand new to this, so please forgive any naivete that I may have:

I’m trying to use a button to “copy-to-clipboard” a WooCommerce product SKU (on single product page). The button will then open a different page where the SKU can be pasted.

I’ve been able to display the SKU on the page with this:
(In the photo the SKU is “Bespoke Item Code: CB_BL_BrTW_01”)

/*Display SKU on Single Product Page */

add_action('woocommerce_after_add_to_cart_form', 'wdm_show_sku');
function wdm_show_sku(){
global $product;
echo $product->get_sku();
}

And I’ve made the button that opens the page and target anchor:

/**BUTTON LINK TO Customization Page from Single Product Page*/

add_action('woocommerce_after_add_to_cart_form', 'button_link_to_bespoke_page');
function button_link_to_bespoke_page(){
echo '<a href="https://www.website.com/page/#anchortojump" target="_blank">
    <button type="button" style="font-size:10px;padding-left:15px;padding-right:15px;margin-left:20px;margin-right:20px">CUSTOMIZE</button>
    </a>';
}

And I found this code that I would like to use this code to copy the SKU to the clipboard (and eventually – somehow- get it pasted into the form field of the target page):

<button onclick="copyText()">CUSTOMIZE</button>

<script>
function copyText() {
  // Get the div element
  var divElement = document.getElementById("copytextid");

  // Create a range object
  var range = document.createRange();

  // Select the contents of the div element
  range.selectNode(divElement);

  // Add the range to the user's selection
  window.getSelection().addRange(range);

  // Copy the selected text to the clipboard
  document.execCommand("copy");

}
</script>

I tried to inspect the page to see if the SKU already has an id, but had no luck (id: “”). Is there any way to give the SKU an id? Or change the last code (document.getElementBy) to find the SKU (which will obviously vary by product/page)?

Thanks!
enter image description here

How to remove label borders in leaflet javascript

I was able to change the size of the circleMarker to a small green dot but the label white space and border covers my study area.
How can I remove the label mylabel borders leaving just the text. Using leaflet and R I can remove it but I am not familiar with
javascript yet. Mock example below:

library(leaflet)
library(htmlwidgets)

leaflet() %>%
  addTiles() %>%
  setView(lng = -121.2722, lat = 38.1341, zoom = 10) %>%
  addMiniMap(tiles = providers$OpenStreetMap, position = 'topleft', width = 250, height = 420) %>%
  onRender("
function(el, x) {
  var map = this;
  if (map.minimap && map.minimap._miniMap) {
    var mini = map.minimap._miniMap;

 L.circleMarker([37.79577, -121.58426],{radius: 2},)
      .setStyle({color: 'green'})
      .bindTooltip('mylabel', {permanent: true, direction: 'right'})
       .addTo(mini);
  }
}
")

TypeScript equivalent of Kotlin Array.any()

I’m still very new to TypeScript. Working on a Next.js project I am displaying a list of grouped items with titles. If there are no items in the group meeting a specific criteria, I don’t want to display the title or the items. I’ve used the Kotlin Array.any() function before as a way of saying “if any item matches this criteria, include it”. I haven’t found a way to do this in TypeScript directly. In the example below, I’d like to keep the Item list if any of it’s items have a someProp = null. The only way I’ve found to do this, so far, is using !Array.every() but the double negative “not every item.someProp not null” is really heavy on the cognitive complexity. Is there a better way to accomplish this?

{Object.entries(groupedListData!)
  .filter(
    ([key, itemsGroupedByKey]) =>
      !itemsGroupedByKey.every(
        (item) => item.someProp !== null
      )
    )
  ...

I’ve read over all of the Array functions and none of them seem to really fit. I’ve also read about extending the built-in Array class with my own any() but that seems a bit heavy-handed. I won’t need this for more than a few spots in the code.

how to create edit function in my todo app vanilla js? [closed]

I have created a todo list with title , description, due dates and priority. But when i click on edit button it waits for 2nd click for editing. How to correctly write edit function for editing form and displays the updated (edited) task.

https://jsfiddle.net/n9ghxbqs/

function addTask(){
  let title = document.querySelector('#title').value
  let des = document.querySelector('#des').value
  let duedate = document.querySelector('#due-date').value
  let priority = document.querySelector('#priority').value

  let newlist = new Todo(title,des,duedate,priority)

  myTodoList.push(newlist)
  render()
  todoForm.style.display = 'none'
}

function render(){
 let list = document.querySelector('.list')
 list.innerHTML = ''

 for(let i = 0; i < myTodoList.length;i++){
  let task = myTodoList[i]
  
  let todoEl = document.createElement('div')
    todoEl.innerHTML = `<div class="book-grid">
      <h3>${task.title}</h3>
      <p>${task.des}</p>
      <p>${task.duedate}due </p>
      <p>${task.priority} priority</p> 

      <div class="f-btn">
      <button class="status" onclick="edit()">edit
      </button>
      <button class="delete" >
        Remove
      </button>
      </div>`;

      list.appendChild(todoEl)

 }

}

function edit(){
  let edit = document.querySelectorAll('.status')

  edit.forEach((editbtn)=>{
    editbtn.addEventListener('click',(e)=>{
      if(e.currentTarget){
        addTodo()
       
      }
    })
  })
 
} ```


 

How do I use a variable as a js object key when searching? [duplicate]

I have a simple program I’m testing where I take a user’s input ID and use that to gather data from a js object; however, I can’t seem to figure out how to use a variable as search for this.

Here’s the current code:
index.html

...
<body>
  <p id="displayTest">...</p>
  <input id="inputTextbox" type="text"></input>
  <input type="submit" onclick="submitID()"></input>
  <script src="script.js"></script>
</body>
...

script.js

var root = {
             data:{
               7292:{
                 ...
               },
               8323:{
                 ...
               }
            }
var display = document.getElementByID("displayTest");
var input = document.getElementByID("inputTextbox");
function submitID() {
  if ((input.value) in (root.data)) {
    display.innerText = root.data/*.the user's input.somedata*/;
    } else {
    display.innerText = "failed :(";
    }
}

It’s important that I am able to get the key in a search like this (root.data.User’s Input.somedata) so that I am able to access data under the input ID; for example, name.

I’ve searched around and still couldn’t find it, so I started trail and error, here’s a few of things I’ve tried:

...
var inputID = input.value;
function submitID() {
  ...
  display.innerText = root.data.inputID.somedata; /*Doesn't return anything, I believe it's looking for a key called 'inputID'*/
  ...
  }
...
...
function submitID() {
  ...
  display.innerText = root.data.${inputID}.somedata; /*Identifier Expected syntax error*/
  ...
  }
...
...
function submitID() {
  ...
  display.innerText = root.data.(input.value).somedata; /*Identifier Expected syntax error*/
  ...
  }
...

I can’t think of any other way to do this, and searching the web has been to no avail, so I turn to you, stackoverflow community, to help me.

Thanks in advance!

TDLR: I am trying to use a variable input as the key for a search in a js object

The code I wrote here is handwritten (not copy/pasted, so it may differ from the actual project), and is written on a device I am unfamiliar with. Assume misspellings & common syntax errors are fixed in project.

Google Gantt Chart in Razor Pages with SQL [closed]

Google Gantt charts… you’ve probably heard of them and maybe even used them. They are easy to toss into a Razor Page when you provide static data for the rows. But, I’m wanting to pull the data from a database table on our SQL server and populate the Gantt chart. I have read countless articles about using PHP and Json files, none have worked for me. I can get the data to populate an HTML table, so I know the data is there. I just can’t format it properly to show in the Gantt Chart. I won’t post any of my code because it’s really just a bunch of snippets of the stuff I’ve found online, including using Ajax calls to get data. Can someone please point me to a modern working example (with source code) of a Google Gantt chart pulling data from a database to successfully populate the chart? This can be in either Razor pages or Blazor. Any help would be greatly appreciated.

Also, I know there are a lot of commercial charts I can use for Razor and Blazor, but we can’t spend any money on this project, which is why I’m trying to use the Google Gantt chart.

Thank you for your time!

UPDATE:
I know I said I wouldn’t post code, but here are the generic example that works, and then the one I can’t get to work…

This one with static data in the rows works:

<h5 style="text-align: center"><u>Written Report Chart</u></h5>

<script type="text/javascript">
    google.charts.load('current', {'packages':['gantt']});
    google.charts.setOnLoadCallback(drawChart);

    function daysToMilliseconds(days) {
      return days * 24 * 60 * 60 * 1000;
    }

    function drawChart() {

      var data = new google.visualization.DataTable();
      data.addColumn('string', 'Task ID');
      data.addColumn('string', 'Task Name');
      data.addColumn('date', 'Start Date');
      data.addColumn('date', 'End Date');
      data.addColumn('number', 'Duration');
      data.addColumn('number', 'Percent Complete');
      data.addColumn('string', 'Dependencies');

      data.addRows([
        ['Research', 'Find sources',
         new Date(2015, 0, 1), new Date(2015, 0, 5), null,  100,  null],
        ['Write', 'Write paper',
         null, new Date(2015, 0, 9), daysToMilliseconds(3), 25, 'Research,Outline'],
        ['Cite', 'Create bibliography',
         null, new Date(2015, 0, 7), daysToMilliseconds(1), 20, 'Research'],
        ['Complete', 'Hand in paper',
         null, new Date(2015, 0, 10), daysToMilliseconds(1), 0, 'Cite,Write'],
        ['Outline', 'Outline paper',
         null, new Date(2015, 0, 6), daysToMilliseconds(1), 100, 'Research']
      ]);

      var options = {
        height: 275
      };

      var chart = new google.visualization.Gantt(document.getElementById('WrittenReport'));

      chart.draw(data, options);
    }
</script>

<div id="WrittenReport" class="chart-container"></div>
<div class="page-divider"></div>

And here is the code for the one that doesn’t work:
In my ‘CSHTML’…

@page
@model ProdSchedPortal.Pages._Testing.AnotherTestModel
@{
}

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
    google.charts.load('current', { 'packages': ['gantt'] });
    google.charts.setOnLoadCallback(drawChart);
    function drawChart() {
        $.ajax({
            type: "POST",
            url: "?handler=ListFilter",
            data: {},
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            success: function (response) {
                // var data = new google.visualization.DataTable(JSON.parse(response));

                var data = new google.visualization.DataTable();
                data.addColumn('string', 'Task ID');
                data.addColumn('string', 'Task Name');
                data.addColumn('date', 'Start Date');
                data.addColumn('date', 'End Date');
                data.addColumn('number', 'Duration');
                data.addColumn('number', 'Percent Complete');
                data.addColumn('string', 'Dependencies');



                const formattedRows = response.map((row, index) => {
                    return [
                        String(index + 1),
                        `${row["OpDesc"]} (${row["JobNum"]})`,
                        new Date(row["StartDate"]),
                        new Date(row["JobOper_DueDate"]),
                        null,
                        parseFloat(row["EstProdHours"]) || 0,
                        null
                    ];
                });
                data.addRows(formattedRows);



                // for (var i = 0; i < response.d.length; i++) {
                //     var taskId = response.d[i][0].toString();
                //     var taskname = response.d[i][1].toString();
                //     var resource = response.d[i][2].toString();
                //     var startDate = new Date(response.d[i][3]).toString();
                //     var enddate = new Date(response.d[i][4]).toString();
                //     var duration = parseInt(response.d[i][5]);
                //     var percentageComplete = parseInt(response.d[i][6]);
                //     var dependencies = response.d[i][7].toString();
                //     data.addRows([[taskId, taskname, resource, startDate, enddate, duration, percentageComplete, dependencies]]);
                // }

                var options = {
                    height: 400, width: 500, gantt: { trackHeight: 30 }
                };

                var chart = new google.visualization.Gantt(document.getElementById('chart_div'));
                chart.draw(data, options);
            }, error: function (response) {
                alert(response.responseText);
            }
        });
    }
</script>

<div id="chart_div" style="height: 180px; margin-top: 50px; border: 1px solid dimgray;"></div>

And in my ‘HTML’, which I made static row data for this example…

public JsonResult? OnPostListFilter()
{
    // Get the DataTable from Database.
    DataTable dt = new DataTable();
    dt.Columns.Add("Task ID", typeof(string));
    dt.Columns.Add("Task Name", typeof(string));
    dt.Columns.Add("Resource", typeof(string));
    dt.Columns.Add("Start Date", typeof(string));
    dt.Columns.Add("End Date", typeof(string));
    dt.Columns.Add("Duration", typeof(int));
    dt.Columns.Add("Percent Complete", typeof(int));
    dt.Columns.Add("Dependencies", typeof(string));

    dt.Rows.Add("2014Spring", "Spring 2014", "spring", new DateTime(2014, 2, 22, 0, 30, 0), new DateTime(2014, 5, 20, 6, 30, 0), null, 100, null);
    dt.Rows.Add("2014Summer", "Summer 2014", "summer", new DateTime(2014, 5, 21, 6, 45, 0), new DateTime(2014, 8, 20, 7, 0, 0), null, 100, null);
    dt.Rows.Add("2014Autumn", "Autumn 2014", "autumn", new DateTime(2014, 8, 21, 7, 4, 0), new DateTime(2014, 11, 20, 7, 30, 0), null, 100, null);
    dt.Rows.Add("2014Winter", "Winter 2014", "winter", new DateTime(2014, 11, 21, 7, 30, 0), new DateTime(2015, 2, 21, 8, 30, 0), null, 100, null);
    dt.Rows.Add("2015Spring", "Spring 2015", "spring", new DateTime(2015, 2, 22), new DateTime(2015, 5, 20), null, 50, null);
    dt.Rows.Add("2015Summer", "Summer 2015", "summer", new DateTime(2015, 5, 21), new DateTime(2015, 8, 20), null, 0, null);
    dt.Rows.Add("2015Autumn", "Autumn 2015", "autumn", new DateTime(2015, 8, 21), new DateTime(2015, 11, 20), null, 0, null);
    dt.Rows.Add("2015Winter", "Winter 2015", "winter", new DateTime(2015, 11, 21), new DateTime(2016, 2, 21), null, 0, null);
    dt.Rows.Add("Football", "Football Season", "sports", new DateTime(2014, 8, 4), new DateTime(2015, 1, 1), null, 100, null);
    dt.Rows.Add("Baseball", "Baseball Season", "sports", new DateTime(2015, 2, 28), new DateTime(2015, 9, 20), null, 14, null);
    dt.Rows.Add("Basketball", "Basketball Season", "sports", new DateTime(2014, 9, 28), new DateTime(2015, 5, 20), null, 86, null);
    dt.Rows.Add("Hockey", "Hockey Season", "sports", new DateTime(2014, 9, 8), new DateTime(2015, 5, 21), null, 89, null);

    List<object> chartData = new List<object>();
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        chartData.Add(new object[] {
    dt.Rows[i][0], dt.Rows[i][1], dt.Rows[i][2], dt.Rows[i][3],dt.Rows[i][4],
    dt.Rows[i][5]==DBNull.Value?0:dt.Rows[i][5], dt.Rows[i][6], dt.Rows[i][7]==DBNull.Value?"":dt.Rows[i][7]
});
    }

    return new JsonResult(chartData);
}

All I get is a blank alert and screen…

enter image description here

How to make Divs to appear side-by-side without changing the HTML structure, only using CSS

I want to pair each .dropdown-select div with its corresponding .phone div, such that:

  • The first .dropdown-select and the first .phone appear on the same
    line,
  • The second .dropdown-select and the second .phone appear on the
    next line, and so on.

The .dropdown-select will occupy 25% space and .phone will occupy 75% space.

The divs are generated dynamically, hence I cannot change the positioning or modify the HTML structure. Need to use CSS entirely for positioning. Tried different techniques, not successful.

And the divs with class as text should not be affected with flex(should not be changed) only divs with class dropdown-select and phone.

/* Main container that holds all the input fields */
.contactFormContainer .field__group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}

/* Ensure each .dropdown-select and .phone div takes up 50% of the container width */
.contactFormContainer .dropdown-select,
.contactFormContainer .phone {
  display: flex;
  flex-direction: column;
  width: calc(50% - 5px);
  /* Make sure each takes up 50% of the space with 5px margin */
}

/* Ensure input fields inside dropdown-select and phone take full width */
.contactFormContainer .dropdown-select__input,
.contactFormContainer .phone__container input {
  width: 100%;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

/* The .text divs remain as block-level elements */
.contactFormContainer .text {
  display: block;
  margin-bottom: 10px;
}

/* Media Query for smaller screens */
@media (max-width: 768px) {
  .contactFormContainer .field__group {
    flex-direction: column;
    /* Stack everything vertically on small screens */
  }

  .contactFormContainer .dropdown-select,
  .contactFormContainer .phone {
    width: 100%;
    /* Full width for small screens */
  }
}
<div class="contactFormContainer">
  <div class="field__group">
    <div class="text">
      <label for="per_email_1">
            Personal eMail 1
          </label>
      <div class="text__count   ">
        <input type="Text" name="per_email_1" aria-label="per_email_2" id="per_email_1_a_1"
            placeholder="Personal eMail 2" minlength="8" maxlength="70" pattern="^[a-zA-Z0-9_%+-]+([a-zA-Z0-9_%+.-]+)@(?!.*?..)([a-zA-Z0-9_-.]+).([a-zA-Z]{2,5})"
            value="">
      </div>
    </div>
    <div class="text">
      <label for="per_email_2">
            Personal eMail 2
          </label>
      <div class="text__count   ">
        <input type="Text" name="per_email_2" aria-label="office_email_1" id="per_email_2_a_1"
            placeholder="Office Email1" minlength="8" maxlength="70" pattern="^[a-zA-Z0-9_%+-]+([a-zA-Z0-9_%+.-]+)@(?!.*?..)([a-zA-Z0-9_-.]+).([a-zA-Z]{2,5})"
            value="">
      </div>
    </div>
    <div class="text">
      <label for="per_email_3">
            Personal eMail 3
          </label>
      <div class="text__count   ">
        <input type="Text" name="per_email_3" aria-label="office_email_2" id="per_email_3_a_1"
            placeholder="Office Email 2" minlength="8" maxlength="70" pattern="^[a-zA-Z0-9_%+-]+([a-zA-Z0-9_%+.-]+)@(?!.*?..)([a-zA-Z0-9_-.]+).([a-zA-Z]{2,5})"
            value="">
      </div>
    </div>
    <div class="dropdown-select " id="mobile_1">
      <label for="mobile_1">
            Mobile No. 1
          </label>
      <div class="dropdown-container">
        <div class="dropdown-select__field ">
          <input type="text" class="dropdown-select__input" id="mobile_1_a_1" placeholder="">
        </div>
      </div>
      <span class="">
          </span>
    </div>
    <div class="dropdown-select " id="mobile_2">
      <label for="mobile_2">
            Mobile No. 2
          </label>
      <div class="dropdown-container">
        <div class="dropdown-select__field ">
          <input type="text" class="dropdown-select__input" id="mobile_2_a_1" placeholder="">
        </div>
      </div>
      <span class="">
          </span>
    </div>
    <div class="dropdown-select " id="mobile_3">
      <label for="mobile_3">
            Mobile No. 3
          </label>
      <div class="dropdown-container">
        <div class="dropdown-select__field ">
          <input type="text" class="dropdown-select__input" id="mobile_3_a_1"
              placeholder="">
        </div>
      </div>
      <span class="">
          </span>
    </div>
    <div class="dropdown-select " id="mobile_4">
      <label for="mobile_4">
            Mobile No. 4
          </label>
      <div class="dropdown-container">
        <div class="dropdown-select__field ">
          <input type="text" class="dropdown-select__input" id="mobile_4_a_1"
              placeholder="">
        </div>
      </div>
      <span class="">
          </span>
    </div>
    <div class="dropdown-select " id="mobile_5">
      <label for="mobile_5">
            Mobile No. 5
          </label>
      <div class="dropdown-container">
        <div class="dropdown-select__field ">
          <input type="text" class="dropdown-select__input" id="mobile_5_a_1"
              placeholder="">
        </div>
      </div>
      <span class="">
          </span>
    </div>
    <div class="dropdown-select " id="mobile_6">
      <label for="mobile_6">
            Mobile No. 6
          </label>
      <div class="dropdown-container">
        <div class="dropdown-select__field ">
          <input type="text" class="dropdown-select__input" id="mobile_6_a_1"
              placeholder="">
        </div>
      </div>
      <span class="">
          </span>
    </div>
    <div class="phone" id="mobile_1_add">
      <label for="mobile_1_add">
          </label>
      <div class="phone__container ">
        <input type="text" name="mobile_1_add" id="mobile_1_add_a_1" placeholder=""
            minlength="8" maxlength="8" pattern="^[89]d{7}$" value="">
      </div>
    </div>
    <div class="phone" id="mobile_2_add">
      <label for="mobile_2_add">
          </label>
      <div class="phone__container ">
        <input type="text" name="mobile_2_add" id="mobile_2_add_a_1" placeholder=""
            minlength="8" maxlength="8" pattern="^[89]d{7}$" value="">
      </div>
    </div>
    <div class="phone" id="mobile_3_add">
      <label for="mobile_3_add">
          </label>
      <div class="phone__container ">
        <input type="text" name="mobile_3_add" id="mobile_3_add_a_1" placeholder=""
            minlength="8" maxlength="8" pattern="^[89]d{7}$" value="">
      </div>
    </div>
    <div class="phone" id="mobile_4_add">
      <label for="mobile_4_add">
          </label>
      <div class="phone__container ">
        <input type="text" name="mobile_4_add" id="mobile_4_add_a_1" placeholder=""
            minlength="8" maxlength="8" pattern="^[89]d{7}$" value="">
      </div>
    </div>
    <div class="phone" id="mobile_5_add">
      <label for="mobile_5_add">
          </label>
      <div class="phone__container ">
        <input type="text" name="mobile_5_add" id="mobile_5_add_a_1" placeholder=""
            minlength="8" maxlength="8" pattern="^[89]d{7}$" value="">
      </div>
    </div>
    <div class="phone" id="mobile_6_add">
      <label for="mobile_6_add">
          </label>
      <div class="phone__container ">
        <input type="text" name="mobile_6_add" id="mobile_6_add_a_1" placeholder=""
            minlength="8" maxlength="8" pattern="^[89]d{7}$" value="">
      </div>
    </div>
  </div>
</div>