Get submitted button’s name in Sveltekit actions

I’ve got a form with 2 buttons:

<form method="POST" class="pt-10">
<div class="flex flex-row pt-10">
                <button type="submit" name="save-and-exit" class="btn btn-primary btn-lg">{ mode == "new" ? "Save and Exit" : "Update and Exit" }</button>
            </div>

            <div class="flex flex-row pt-10">
                <button type="submit" name="add-tracks" class="btn btn-primary btn-lg">{ "-> Tracks" }</button>
            </div>
</form>

Omitting the fields in form for simplicity.

My action looks like this:

export const actions = {
    default: async ({ request, fetch }) => {

        // create API instance
        const recordAPI = new RecordAPI(fetch);

        // retrieve the data from the form
        const data = Object.fromEntries(await request.formData());

        // validate data and create DTO
        const record = recordDTO(data);

        // if errors returned from building the DTO (validation errors) then return the object.
        if (record?.errors && !emptyObject(record.errors)) {
            return {
                "data": record.data,
                "errors": record.errors,
            };
        }

        // save the data
        const response = await recordAPI.post(record);

        if (response.status == 200) {
            throw redirect(302, '/records')
        }

        return {
            data: record,
            "errors": response.errors,
        }
}

In the action function, is there a way to know which of the 2 buttons was the one that submitted the form? I need to know this since the flow is gonna be different depending on that.

One solution I can think of is updating the form to something like this:

<form method="POST" bind:this={formElement}>

then manually append the name of the button to the form and trigger formElement.requestSubmit(), but I was wondering if there’s a way to do it directly in the action, I believe it looks more ‘elegant’.

Thanks.

can we pass a part of array into another array through spread operator in javascript? [duplicate]

I want to pass only a part of array into another array through spread operator.

I tried passing an entire array into another array with spread operator.It worked.

let array1 = [1,2,3,4,5];
let array2  = [...array1, 6,7,8];
console.log(array2);

I expect to pass only first 3 elements of array [1,2,3] through spread operator into another array. How to do that?

Nuxt 3 directive and updating component data

I made a directive because I would like to be able to detect when a mouse click was outside of a specific element. I will use this for a dropdown menu.

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.vueApp.directive('detect-click-outside', {
        mounted (el) {
            el.clickOutsideEvent = function (event) {
                // // here I check that click was outside the el and his children
                if (!(el == event.target || el.contains(event.target))) {
                    // and if it did, change data from directive
                    console.log("click is inside")
                }

                console.log("click is outside")
                // update a value (name: clickedOutside) in the component
                // where this directive is used
            };

            document.body.addEventListener('click', el.clickOutsideEvent)
        },
    })
})

The problem I am facing, and unable to find an answer for on the internet, is how I can update “data” from the component in which the directive is used.

For example:

const clickedOutside = false;

When I click outside, the directive should update the above line in the component used. For example the “mainMenu” component.

Does anyone know how I can do that?

I can’t find it in the Nuxt manual. For Vue it would be something like vnode.context.isDropdwonMenuVisible = false;, but for Nuxt 3 I am unable to find such a thing.

FYI I am using the <script setup> method in Nuxt.

Sample code of the menu:

<script setup>
const isDropdwonMenuVisible = ref(false);
</script>


<template>
  <div class="mx-auto max-w-screen-2xl flex border-b border-gray:50 py-4 text-sm" v-detect-click-outside>
    <div class="flex items-center text-lg font-bold cursor-pointer" v-for="(dataKey, dataIndex) in data" :keydata="dataIndex" @click="currentOpened = dataIndex">
      {{ dataIndex }} <img src="images/icons/chevron-down-solid.svg" width="12px" class="ml-4" />
    </div>
    {{ currentOpened }}
  </div>
</template>

problem in reloading iframe with updated src

So I have a window where there is an Iframe named containerframe and within that iframe I have another iframe named pcpFrame.

From pcpFrame Iframe I postMessage to raise a message event for the grandparent (parent iframe’s parent) using :
window.parent.parent.postMessage(message, '*');

In the grand-parent window I am listening to message event and execute following piece of code :

window.addEventListener('message', function (e) {
    // Get the sent data
    let iframe = window.document.getElementById("frmRightSide");
    console.log('data json', e.data)
    let msg = JSON.parse(e.data)
    if (msg?.refresh == true){
        alert("updating iframe");
        iframe.src = "https://codepen.io/pen/";
        // iframe.contentWindow.location.reload(true);
        alert("updated");
    }
});

Expected behavior :
Initially the parent iframe (called containerFrame) has pre-loaded webpage with src="https://www.youtube.com/watch?v=qz0aGYrrlhU" and after processing this message event I want to reload this parent iframe with updated src='https://codepen.io/pen'

Actually behavior :
What currently happens is that, this reloads the parent iframe (containerFrame) but instead of loading the iframe with updated src='https://codepen.io/pen/', it re-fetches the webpage with original iframe src='https://www.youtube.com/watch?v=qz0aGYrrlhU'


There are two strange things :

  1. After message event is processed (and not debugging) I saw some conflict through some console logging :
    console.log(iframe.src) // prints updated src for codepen page
    console.log(iframe.contentDocument.location) // prints previous src for youtube page
    similar thing gets reflected in the HTML elements panel too :
<iframe id="frmRightSide" width="100%" frameborder="0" scrolling="auto" style="z-index: -1; overflow-x: hidden;" onload="setIframeHeight(this)" height="1119.2px" src="https://codepen.io/pen/">
#document (https://www.youtube.com/watch?v=qz0aGYrrlhU)
<html>
<! –– rest of the code removed as no issue here ––>
</html>
</iframe>
  1. If I do this while debugging the callback of message event, iframe loads page from upated src, i.e. codepen webpage

Why order of sloppy-mode function statement in block affects global variable differently?

snippet 1 -> output is “b”


if (true) {
  x = "b";
  function x() {}
}
console.log(x); //b

snippet 2 -> output is ƒ x() {}


if (true) {
  function x() {}
  x = "b";
}
console.log(x); // ƒ x() {}

I know that using strict mode will not affect the global variable at all, but I want to know how x is being assigned different values when strict mode is disabled.

Take a Ten Minutes Walk. What’s wrong?

I am trying to solve this Codewars question (https://www.codewars.com/kata/54da539698b8a2ad76000228/train/javascript) but something doesn’t work. I don’t know what’s wrong with my approach.Here is my code:

    function isValidWalk(walk) {
  if(walk.length > 10 || walk.length < 10){
    return false
  }else (walk.splice(0,5).join('') == walk.splice(5,5).map(x=>{
    if(x =='s'){
      return 'n'
    }else if(x=='n'){
      return 's'
    }
    else if(x=='w'){
      return'e'
    }
    else if(x=='e'){
      return 'w'
    }
  }).join(''))
    return true
  
}

Description of the question:

You live in the city of Cartesia where all roads are laid out in a perfect grid. You arrived ten minutes too early to an appointment, so you decided to take the opportunity to go for a short walk. The city provides its citizens with a Walk Generating App on their phones — everytime you press the button it sends you an array of one-letter strings representing directions to walk (eg. [‘n’, ‘s’, ‘w’, ‘e’]). You always walk only a single block for each letter (direction) and you know it takes you one minute to traverse one city block, so create a function that will return true if the walk the app gives you will take you exactly ten minutes (you don’t want to be early or late!) and will, of course, return you to your starting point. Return false otherwise.

Note: you will always receive a valid array containing a random assortment of direction letters (‘n’, ‘s’, ‘e’, or ‘w’ only). It will never give you an empty array (that’s not a walk, that’s standing still!).

Default homepage isn’t visible on pageload

I was creating a navbar in React with Bootstrap and adding navigation links. I’m learning to use React Router and my main App.js file looks like this:

import './App.css';
import {
  BrowserRouter as Router,
  Route,
  Link,
  Routes,
  Outlet,
} from "react-router-dom";
import { Navbar, Nav } from "react-bootstrap";
import { FaHome,  FaBook,  FaBookReader } from "react-icons/fa";
import Home from './Components/Home';
import Thrillers from './Components/Thrillers';
import Classics from './Components/Classics';
import Nonfiction from './Components/Nonfiction';
import Romance from './Components/Romance';
import Sciencefiction from './Components/Sciencefiction';
function App() {
  return (
    <div className="App">
   
    <Router>
            <Navbar className="navbar-bg" expand="lg">
                <Navbar.Brand>
                    <h1 className="navbar-brand-text">
                        <Link to="/" className="brand-link">
                        <FaBookReader /> Rupesh Gupta 
                        </Link>
                    </h1>
                </Navbar.Brand>
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">
                    <Nav className="ml-auto">
                        <Nav.Link as={Link} to="/" className="nav-link">
                            <FaHome /> Home
                        </Nav.Link>
                        <Nav.Link as={Link} to="/thrillers" className="nav-link">
                            <FaBook /> Thrillers
                        </Nav.Link>
                        <Nav.Link as={Link} to="/classics" className="nav-link">
                            <FaBook /> Classics
                        </Nav.Link>
                        <Nav.Link as={Link} to="/nonfiction" className="nav-link">
                            <FaBook /> Non Fiction
                        </Nav.Link>
                        <Nav.Link as={Link} to="/romance" className="nav-link">
                            <FaBook /> Romance
                        </Nav.Link>
                        <Nav.Link as={Link} to="/sciencefiction" className="nav-link">
                            <FaBook /> Science Fiction
                        </Nav.Link>
                    </Nav>
                </Navbar.Collapse>
            </Navbar>
            <div className="container mt-4">
                <Routes>
                    <Route path="/" element={<Outlet />}>
                        <Route index element={<Home />} />
                        
                        <Route path="/thrillers" element={<Thrillers />} />
                        <Route path="/classics" element={<Classics />} />
                        <Route path="/nonfiction" element={<Nonfiction />} />
                        <Route path="/romance" element={<Romance />} />
                        <Route path="/sciencefiction" element={<Sciencefiction />} />
                    </Route>
                </Routes>
            </div>
        </Router>
    </div>
  );
}

export default App;

The issue that I am having is that when the page initially loads (after “npm start” or upon visiting where it’s deployed on github-pages) the Home component isn’t displayed. However, when I navigate to “Home” or “Rupesh Gupta” (via the Links in the Navbar component) Home component is displayed. Other links in navbar work as expected. If I kill the development server and restart it, the homepage no longer loads. Any advice? Thanks.

My if else statement only behaves as though the condition is true. Even if it is entered incorrectly

Good day!

I am taking the javascript basics course on treehouse. I am brand new to this learning processes.

I have included all of my javascript code and the directions at the bottom. I am making a basic quiz acrewing the correct number of answers and awarding a “crown” at the end that indicates the level of success.

Since starting this course I have went back and taken the html and css course. I will do things differently in the future. But I have spend so much time on this project I NEED to make it work.

Thank you for your time.

My intention is to utilize the else if statement to determine the response according to how many questions are correct. I have started by just trying to utilize the if else statement for the first part of the solution and I can not get the condition to state the false response. I figured after I get this correct I can create the else if statements.

const me = prompt('n What is your name?n');

const greating = alert(`n Good day ${me}! nnThis is a quiz about Apis mellifera.  Increase your rank by answering correctly.`);

let record = 0;

alert(`n Correct Answers: ${record}`);


const one = prompt('n 1. Apis mellifera is the scientific name for what non-native insect?n');
if (one.toUpperCase() === 'european honeybee'.toUpperCase() || one.toUpperCase() === 'honeybee'.toUpperCase() 
|| one.toUpperCase() === 'bee'.toUpperCase() || one.toUpperCase() === 'european honey bee'.toUpperCase() 
|| one.toUpperCase() === 'honey bee'.toUpperCase()) 

{ alert('n That is correct!!')
  alert(`n Correct Answers: ${record += 1}`)
} 
  else alert('n This is NOT correct.')
{ alert(`n Correct Answers: ${record += 0}`)
}

const two = prompt('n 2. Name one of the three types of adult European honeybees in a colony?n');
if (two.toUpperCase() === 'queen'.toUpperCase() || two.toUpperCase() === 'queens'.toUpperCase() ||
    two.toUpperCase() === 'drone'.toUpperCase() || two.toUpperCase() === 'drones'.toUpperCase() ||
    two.toUpperCase() === 'worker'.toUpperCase() || two.toUpperCase() === 'workers'.toUpperCase()) 
{ alert('n That is correct!!')
  alert(`n Correct Answers: ${record += 1}`)
}
  else alert('n This is NOT correct.')
{ alert(`n Correct Answers: ${record += 0}`)
}

const three = prompt('n 3. How does the queen communicate with her colony?n');
if (three.toUpperCase() === 'pheromones'.toUpperCase() || three.toUpperCase() === 'scent'.toUpperCase() ||
    three.toUpperCase() === 'chemicals'.toUpperCase() || three.toUpperCase() === 'her musk'.toUpperCase()) 
{ alert('n That is correct!!')
  alert(`n Correct Answers: ${record += 1}`)
} 
  else alert('n This is NOT correct.')
{ alert(`n Correct Answers: ${record += 0}`)
}

const four = prompt('n 4. How do worker bees tell other workers where to find food sources?n');
if (four.toUpperCase() === 'waggle dance'.toUpperCase() || four.toUpperCase() === 'dance'.toUpperCase() ||
    four.toUpperCase() === 'dancing'.toUpperCase() || four.toUpperCase() === 'wiggling her tukas'.toUpperCase()) 
{ alert('n That is correct!!')
  alert(`n Correct Answers: ${record += 1}`)
} 
  else alert('n This is NOT correct.')
{ alert(`n Correct Answers: ${record += 0}`)
}

const five = prompt('n 5. What is the name of the mite that is desicrating the Apis mellifera population?n');
if (five.toUpperCase() === 'Veroa destructor'.toUpperCase() || five.toUpperCase() === 'Veroa'.toUpperCase() ||
    five.toUpperCase() === 'blood sucking, virus carrying bastards'.toUpperCase()) 
{ alert('n That is correct!!')
  alert(`n Correct Answers: ${record += 1}`)
} 
  else alert('n This is NOT correct.')
{ alert(`n Correct Answers: ${record += 0}`)
}

alert(`n Total Correct Answers: ${record}`)

if (`${record} == 5`)
 { alert('n Congratulations!  You got them all right.  You award is the gold crown. You are the Queen Bee!')
 } else
 { alert('n The bees need you to do better.')
 }


/*
0.0 directions 
  1. Store correct answers
   - When quiz begins, no answers are correct
*/


// 2. Store the rank of a player


// 3. Select the <main> HTML element

/*<p>
  
  </p>
*/

/*
  4. Ask at least 5 questions
   - Store each answer in a variable
   - Keep track of the number of correct answers
*/

/*   1.  Apis mellifera is the scientific name for what non-native insect?
    2.  A European honeybee consists of what three types of adult bees?
    3.  How does the quess communicate with her colony?
    4.  How do worker bees tell other workers where to find food sources?
    5  What is the name of the mite that is desicrating the Apis mellifera population?
*/    
/*
  5. Rank player based on number of correct answers
   - 5 correct = Gold
   - 3-4 correct = Silver
   - 1-2 correct = Bronze
   - 0 correct = No crown
*/


// 6. Output results to the <main> element

I saw some people put semicolons in their if else and else if statements. I tried that.

I tried researching the internet for solutions. I think maybe I don’t know the correct questions to ask.

I honestly don’t remember what all I’ve tried. I wanted to figure it out on my own but have waisted so much time on it I figured it was time to reach out for help.

I have tried to review the previous questions to see if they are applicable to me…but I am to ignorant to know if they are the same as my situaiton.

I have no doubt the answer is going to be foolishly simple. Thank you for your time.

Magan

Implementing a Sticky Titles feature

I am trying to implement a sticky titles feature, and I think I am getting too complicated.

This is where I am right now:

class StickyTitles {
  constructor(titlesSelector, containerSelector, distanceFromTopDetection) {
    this.titles = Array.from(document.querySelectorAll(titlesSelector));
    this.container = document.querySelector(containerSelector);

    // Security buffer number to check if the intersection has happened in the top of the container
    this.distanceFromTopDetection = distanceFromTopDetection;
  }

  start() {
    this.setAllTitlesSticky();
    let observer = new IntersectionObserver(this.observerCallback.bind(this), this.observerOptions());
    this.titles.forEach( (e) => observer.observe(e) );
  }

  setAllTitlesSticky() {
    this.titles.forEach((e) => {
      e.style.position = "sticky";
      e.style.top = "0px";
      e.style.zIndex = "9999";
    });
  }

  observerOptions() {
    console.log("this.container:", this.container);
    const containerPaddingTop = window.getComputedStyle(this.container).getPropertyValue("padding-top");
    const containerPaddingTopInPx = parseInt(containerPaddingTop);
    console.log("containerPaddingTop:", containerPaddingTop);
    console.log("containerPaddingTopInPx:", containerPaddingTopInPx);

    return {
      root: this.container,
      rootMargin: `-${containerPaddingTopInPx + 10}px 0px 0px 0px`,
      threshold: [1],
    };
  }

  observerCallback(entries, _observer) {
    console.log("observerCallback");

    // Each entry describes an intersection change for one observed
    // target element:
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
    entries.forEach( (e) => this.intersectionEvent(e) );
  }

  intersectionEvent(entry) {
    const isIntersecting = entry.isIntersecting;
    const top = entry.boundingClientRect.top;

    console.log("intersectionEvent:", entry.target.innerText);
    console.log("isIntersecting:", isIntersecting);
    console.log("top:", top);

    console.log("intersectionRect.top:", entry.intersectionRect.top);
    console.log("rootBounds.top:", entry.rootBounds.top);

    console.log("intersectionRect.bottom:", entry.intersectionRect.bottom);
    console.log("rootBounds.bottom:", entry.rootBounds.bottom);

    if (isIntersecting && Math.abs(entry.intersectionRect.top - entry.rootBounds.top) < this.distanceFromTopDetection) {
      this.delinkTop(entry.target);
    } else if (!isIntersecting && Math.abs(entry.intersectionRect.top - entry.rootBounds.top) < this.distanceFromTopDetection) {
      this.linkTop(entry.target)
    }
  }
  linkTop(element) {
    console.log("linkTop:", element);
    this.allPreviousElementsTransparent(element, this.titles);
    this.allNextElementsVisible(element, this.titles);
    this.elementVisible(element)
  }

  delinkTop(element) {
    console.log("delinkTop:", element);
    this.previousElementVisible(element, this.titles);
  }

  allPreviousElementsTransparent(element) {
    console.log("allPreviousElementsTransparent:", element);
    const index = this.indexElement(element);
    console.log("index:", index);

    // First element has not previous
    if (index === 0) return;

    const previousElements = this.titles.slice(0, index);
    previousElements.forEach((e) => this.elementTransparent(e));
  }

  allNextElementsVisible(element) {
    console.log("allNextElementsVisible:", element);
    const index = this.indexElement(element);

    // Last element has not next
    if (index === this.titles.size - 1) return;

    const nextElements = this.titles.slice(index + 1);
    nextElements.forEach((e) => this.elementVisible(e));
  }

  previousElementVisible(element) {
    console.log("previousElementVisible:", element);

    // First element has not previous
    if (this.indexElement(element) === 0) return;

    const previousElement = this.titles[this.indexElement(element) - 1];
    this.elementVisible(previousElement)
  }

  elementVisible(element) {
    console.log("elementVisible:", element);
    element.classList.remove("transparent");
    element.classList.add("visible");
  }

  elementTransparent(element) {
    console.log("elementTransparent:", element);
    element.classList.remove("visible");
    element.classList.add("transparent");
  }

  indexElement(element) {
    const result =
      this.titles.findIndex((familyElement) => {
        return familyElement == element;
      });

    return result;
  }
}

// new StickyTitles(".message.role-user", "#messages-list", 200).start();

new StickyTitles("h1", "#container", 20).start();
#container {
  margin: 100px;
  height: 400px;
  overflow-y: scroll;
  padding: 50px;
}

#container h1 {
  display: inline;
  background-color: darkkhaki;
}

#container h1.transparent {
  transition: opacity 0.3s;
  opacity: 0;
}

#container h1.visible {
  transition: opacity 0.3s;
  opacity: 1;
}
<html>
<head>
  <title>Test</title>
</head>
<body>
  <div id="container">
    <h1>Title 1</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec leo sit amet est sollicitudin viverra. Etiam
      tincidunt erat et est facilisis, id laoreet sapien bibendum. Nulla rutrum odio sed est vulputate, vitae luctus massa
      hendrerit. Sed sed urna venenatis sem tristique finibus. Donec tristique nisl nibh. Sed non hendrerit nulla. Nulla non
      leo diam.

      Nullam eu magna consequat, laoreet purus nec, luctus augue. Integer porttitor eros at tellus porta tempus. Curabitur
      imperdiet odio velit, ac commodo magna tristique sed. Maecenas ornare blandit mi, in accumsan tellus aliquam vel. Sed
      enim dui, tincidunt at nisi quis, accumsan tempor justo. Donec eget justo interdum, scelerisque ante nec, varius neque.
      Aenean odio tortor, suscipit nec aliquam quis, viverra eget enim. In pharetra aliquam diam, sed sollicitudin elit varius
      id. Morbi pulvinar tincidunt dolor.

      Sed id urna eleifend, vulputate libero ac, tristique ipsum. Nullam porta erat ut tellus vestibulum ultrices. Maecenas
      non est a diam eleifend dictum non vitae magna. Morbi aliquet viverra nunc et laoreet. Integer massa urna, maximus sed
      mi nec, consequat consequat erat. Nulla facilisi. Nullam feugiat ligula vel elit fringilla commodo. Integer a posuere
      nibh, at porttitor risus. Morbi id sem facilisis odio dapibus volutpat sit amet id leo. Nunc id volutpat urna. Nunc eget
      ex vel nibh tincidunt venenatis. Proin congue quis mauris ut luctus.
    </p>

    <h1>Title facilisis sit amet, consectetur</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec leo sit amet est sollicitudin viverra. Etiam
      tincidunt erat et est facilisis, id laoreet sapien bibendum. Nulla rutrum odio sed est vulputate, vitae luctus massa
      hendrerit. Sed sed urna venenatis sem tristique finibus. Donec tristique nisl nibh. Sed non hendrerit nulla. Nulla non
      leo diam.

      Nullam eu magna consequat, laoreet purus nec, luctus augue. Integer porttitor eros at tellus porta tempus. Curabitur
      imperdiet odio velit, ac commodo magna tristique sed. Maecenas ornare blandit mi, in accumsan tellus aliquam vel. Sed
      enim dui, tincidunt at nisi quis, accumsan tempor justo. Donec eget justo interdum, scelerisque ante nec, varius
      neque.
      Aenean odio tortor, suscipit nec aliquam quis, viverra eget enim. In pharetra aliquam diam, sed sollicitudin elit
      varius
      id. Morbi pulvinar tincidunt dolor.

      Sed id urna eleifend, vulputate libero ac, tristique ipsum. Nullam porta erat ut tellus vestibulum ultrices. Maecenas
      non est a diam eleifend dictum non vitae magna. Morbi aliquet viverra nunc et laoreet. Integer massa urna, maximus sed
      mi nec, consequat consequat erat. Nulla facilisi. Nullam feugiat ligula vel elit fringilla commodo. Integer a posuere
      nibh, at porttitor risus. Morbi id sem facilisis odio dapibus volutpat sit amet id leo. Nunc id volutpat urna. Nunc
      eget
      ex vel nibh tincidunt venenatis. Proin congue quis mauris ut luctus.
    </p>

    <h1>Title dolor sit amet</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec leo sit amet est sollicitudin viverra. Etiam
      tincidunt erat et est facilisis, id laoreet sapien bibendum. Nulla rutrum odio sed est vulputate, vitae luctus massa
      hendrerit. Sed sed urna venenatis sem tristique finibus. Donec tristique nisl nibh. Sed non hendrerit nulla. Nulla non
      leo diam.

      Nullam eu magna consequat, laoreet purus nec, luctus augue. Integer porttitor eros at tellus porta tempus. Curabitur
      imperdiet odio velit, ac commodo magna tristique sed. Maecenas ornare blandit mi, in accumsan tellus aliquam vel. Sed
      enim dui, tincidunt at nisi quis, accumsan tempor justo. Donec eget justo interdum, scelerisque ante nec, varius
      neque.
      Aenean odio tortor, suscipit nec aliquam quis, viverra eget enim. In pharetra aliquam diam, sed sollicitudin elit
      varius
      id. Morbi pulvinar tincidunt dolor.

      Sed id urna eleifend, vulputate libero ac, tristique ipsum. Nullam porta erat ut tellus vestibulum ultrices. Maecenas
      non est a diam eleifend dictum non vitae magna. Morbi aliquet viverra nunc et laoreet. Integer massa urna, maximus sed
      mi nec, consequat consequat erat. Nulla facilisi. Nullam feugiat ligula vel elit fringilla commodo. Integer a posuere
      nibh, at porttitor risus. Morbi id sem facilisis odio dapibus volutpat sit amet id leo. Nunc id volutpat urna. Nunc
      eget
      ex vel nibh tincidunt venenatis. Proin congue quis mauris ut luctus.
    </p>

    <h1>Title consequat consequat erat. Nulla facilisi</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec leo sit amet est sollicitudin viverra. Etiam
      tincidunt erat et est facilisis, id laoreet sapien bibendum. Nulla rutrum odio sed est vulputate, vitae luctus massa
      hendrerit. Sed sed urna venenatis sem tristique finibus. Donec tristique nisl nibh. Sed non hendrerit nulla. Nulla non
      leo diam.

      Nullam eu magna consequat, laoreet purus nec, luctus augue. Integer porttitor eros at tellus porta tempus. Curabitur
      imperdiet odio velit, ac commodo magna tristique sed. Maecenas ornare blandit mi, in accumsan tellus aliquam vel. Sed
      enim dui, tincidunt at nisi quis, accumsan tempor justo. Donec eget justo interdum, scelerisque ante nec, varius
      neque.
      Aenean odio tortor, suscipit nec aliquam quis, viverra eget enim. In pharetra aliquam diam, sed sollicitudin elit
      varius
      id. Morbi pulvinar tincidunt dolor.

      Sed id urna eleifend, vulputate libero ac, tristique ipsum. Nullam porta erat ut tellus vestibulum ultrices. Maecenas
      non est a diam eleifend dictum non vitae magna. Morbi aliquet viverra nunc et laoreet. Integer massa urna, maximus sed
      mi nec, consequat consequat erat. Nulla facilisi. Nullam feugiat ligula vel elit fringilla commodo. Integer a posuere
      nibh, at porttitor risus. Morbi id sem facilisis odio dapibus volutpat sit amet id leo. Nunc id volutpat urna. Nunc
      eget
      ex vel nibh tincidunt venenatis. Proin congue quis mauris ut luctus.
    </p>

    <h1>Title at nisi quis</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec leo sit amet est sollicitudin viverra. Etiam
      tincidunt erat et est facilisis, id laoreet sapien bibendum. Nulla rutrum odio sed est vulputate, vitae luctus massa
      hendrerit. Sed sed urna venenatis sem tristique finibus. Donec tristique nisl nibh. Sed non hendrerit nulla. Nulla non
      leo diam.

      Nullam eu magna consequat, laoreet purus nec, luctus augue. Integer porttitor eros at tellus porta tempus. Curabitur
      imperdiet odio velit, ac commodo magna tristique sed. Maecenas ornare blandit mi, in accumsan tellus aliquam vel. Sed
      enim dui, tincidunt at nisi quis, accumsan tempor justo. Donec eget justo interdum, scelerisque ante nec, varius
      neque.
      Aenean odio tortor, suscipit nec aliquam quis, viverra eget enim. In pharetra aliquam diam, sed sollicitudin elit
      varius
      id. Morbi pulvinar tincidunt dolor.

      Sed id urna eleifend, vulputate libero ac, tristique ipsum. Nullam porta erat ut tellus vestibulum ultrices. Maecenas
      non est a diam eleifend dictum non vitae magna. Morbi aliquet viverra nunc et laoreet. Integer massa urna, maximus sed
      mi nec, consequat consequat erat. Nulla facilisi. Nullam feugiat ligula vel elit fringilla commodo. Integer a posuere
      nibh, at porttitor risus. Morbi id sem facilisis odio dapibus volutpat sit amet id leo. Nunc id volutpat urna. Nunc
      eget
      ex vel nibh tincidunt venenatis. Proin congue quis mauris ut luctus.
    </p>

    <h1>Title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec leo sit amet est sollicitudin viverra. Etiam
    tincidunt erat et est facilisis, id laoreet sapien bibendum. Nulla rutrum odio sed est vulputate, vitae luctus massa
    hendrerit</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec leo sit amet est sollicitudin viverra. Etiam
      tincidunt erat et est facilisis, id laoreet sapien bibendum. Nulla rutrum odio sed est vulputate, vitae luctus massa
      hendrerit. Sed sed urna venenatis sem tristique finibus. Donec tristique nisl nibh. Sed non hendrerit nulla. Nulla non
      leo diam.

      Nullam eu magna consequat, laoreet purus nec, luctus augue. Integer porttitor eros at tellus porta tempus. Curabitur
      imperdiet odio velit, ac commodo magna tristique sed. Maecenas ornare blandit mi, in accumsan tellus aliquam vel. Sed
      enim dui, tincidunt at nisi quis, accumsan tempor justo. Donec eget justo interdum, scelerisque ante nec, varius
      neque.
      Aenean odio tortor, suscipit nec aliquam quis, viverra eget enim. In pharetra aliquam diam, sed sollicitudin elit
      varius
      id. Morbi pulvinar tincidunt dolor.

      Sed id urna eleifend, vulputate libero ac, tristique ipsum. Nullam porta erat ut tellus vestibulum ultrices. Maecenas
      non est a diam eleifend dictum non vitae magna. Morbi aliquet viverra nunc et laoreet. Integer massa urna, maximus sed
      mi nec, consequat consequat erat. Nulla facilisi. Nullam feugiat ligula vel elit fringilla commodo. Integer a posuere
      nibh, at porttitor risus. Morbi id sem facilisis odio dapibus volutpat sit amet id leo. Nunc id volutpat urna. Nunc
      eget
      ex vel nibh tincidunt venenatis. Proin congue quis mauris ut luctus.
    </p>
  </div>
</body>
</html>

The main point is that all the titles are “position: sticky.” This was easy. But then I had to make the previous titles invisible so they don’t get messy on the back of the actual title.

This is where things started to get complicated.

I managed to find a solution by detecting the intersection with the top or bottom of the container and making the other siblings visible or invisible.

But then I realized that if I scroll too fast back and forth, the title states start to get messy, like being invisible when they should be visible and vice versa.

I tried to minimize the bugs by making other siblings visible/invisible in many different cases to double-check that the state was right.

Still, the intersection mechanism is not very solid, and I have situations where the titles are not in the right state.

It would be easy if I had a way to:

  • check all the titles that are stuck to the top (position is fixed because they have reached the top)
  • make invisible all of them but the last one

I could call this method on every scroll event, and it should work. But I can’t find a way to detect what titles are actually “stuck” on the top (I can’t find an event for that). Only by intersections and, as mentioned, they are not trustable in quick scrolls.

Any ideas or suggestions would be very appreciate, thanks!

Using two variables in AJAX to refresh an input with values from the database

I have 3 inputs ( generation, fuel and engine) with predefined values.

<div class="row">
                                    <div class="col-md-6 b-submit__main-element wow zoomInUp" data-wow-delay="0.5s">
                                        <label>Generatie <span>*</span></label>
                                        <div class='s-relative'>
                                            <select class="m-select" name="car-generation" id="car-generation">
                                            <option value='0' name='generation_name' id='generation_name'>Alege mai intai un model</option>
                                            </select>
                                            <span class="fa fa-caret-down"></span>
                                        </div>
                                    </div>
                                    <div class="col-md-6 b-submit__main-element wow zoomInUp" data-wow-delay="0.5s">
                                        <label>Combustibil <span>*</span></label>
                                        <div class='s-relative'>
                                            <select class="m-select" name="car-fuel" id="car-fuel">
                                            <option value='0' name='fuel_name' id='fuel_name'>Alege mai intai o generatie</option>
                                            </select>
                                            <span class="fa fa-caret-down"></span>
                                        </div>
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="col-md-6 b-submit__main-element wow zoomInUp" data-wow-delay="0.5s">
                                        <label>Engine <span>*</span></label>
                                        <div class='s-relative'>
                                            <select class="m-select" name="car-engine" id="car-engine">
                                                <option value='0' name='engine_name' id='engine_name'>Alege mai intai un combustibil</option>
                                            </select>
                                            <span class="fa fa-caret-down"></span>
                                        </div>
                                    </div>

So far, when I select something from the generation input, the fuel input shows the needed values. But when I select a fuel from the fuels input, the engines input doesn’t show anything.

This is the JS Code:

$(document).ready(function(){
$('#car-generation').on('change',function(){
        var generation_id = $(this).val();
        if(generation_id > 0){
            $.ajax({
                type:'POST',
                url:'ajax.php',
                data:'generation_id='+generation_id,
                success:function(html){
                    $('#car-fuel').html(html);
                }
            }); 
        }else{
            $('#car-fuel').html('<option value="0">Alege mai intai o generatie</option>'); 
        }
    });
    $('#car-fuel').on('change',function(){
        var fuel_id = $(this).val();
        if(fuel_id > 0){
            $.ajax({
                type:'POST',
                url:'ajax.php',
                data: {fuel_id:'fuel_id', generation_id:'generation_id'},
                success:function(html){
                    $('#car-engine').html(html);
                }
            }); 
        }else{
            $('#car-engine').html('<option value="0">Alege un motor</option>');
        }
    });
    $('#car-engine').on('change',function(){
        var engine_id = $(this).val();
        if(engine_id > 0){
            $.ajax({
                type:'POST',
                url:'ajax.php',
                data:'engine_id='+engine_id,
                success:function(html){
                    $('#car-transmission').html(html);
                }
            }); 
        }else{
            $('#car-transmission').html('<option value="0">Alege o transmisie</option>'); 
        }
    });
});

…and this is the PHP:

<?php
if(isset($_POST["generation_id"]) && !empty($_POST["generation_id"]))

{

  $generation_id = $_POST["generation_id"];

  $query = $mysqli->query("SELECT fuel_id, fuel_name FROM fuels WHERE generation_id =" . $_POST['generation_id']);

  $rowCount = $query->num_rows;

    if($rowCount > 0)
    {
      echo '<option value="0">Alege un combustibil</option>';
        while($row = $query->fetch_assoc())
        { 
          echo '<option value="'.$row['fuel_id'].'">'.$row['fuel_name'].'</option>';
        }
    }else
    {
      echo '<option value="0">Alege un combustibil</option>';
    }

  }
if(isset($_POST["fuel_id"]) && !empty($_POST["fuel_id"]))
{

  $fuel_id = $_POST["fuel_id"];

  $query = $mysqli->query("SELECT engines.engine_id, engines.engine_name FROM engines INNER JOIN generations ON engines.generation_id = generations.generation_id INNER JOIN fuels ON engines.fuel_id = fuels.fuel_id WHERE engines.generation_id = '$generation_id' AND engines.fuel_id = '$fuel_id'");

  $rowCount = $query->num_rows;

    if($rowCount > 0)
    {
      echo '<option value="0">Alege un motor</option>';
        while($row = $query->fetch_assoc())
        { 
          echo '<option value="'.$row['engine_id'].'">'.$row['engine_name'].'</option>';
        }
    }else
    {
      echo '<option value="0">Alege un motor</option>';
    }
}
?>

What am I doing wrong? I don’t have experience with Javascript, AJAX and jquery.

I tried searching for a resolve online, but didn’t find anything

Why this JavaScript function sometimes takes good value and works, and sometimes not? Probably a problem with refresh rate of the page

I’m trying to animate a snake composed of segments.
These segments should retreat when the mouse is stopped.
So I’m calculating the distance and when the mouse is stopped, I’m changing the position and also the opacity value.
Sometimes it works in a good and smooth way, sometimes not.
This is the code of the function:

function animateSnake() {
    let previousX = mouseX;
    let previousY = mouseY;


    segments.forEach((segment, index) => {
        const dx = previousX - segment.x;
        const dy = previousY - segment.y;
        const distance = Math.sqrt(dx * dx + dy * dy);

        if (distance >= segmentSize) {
            const angle = Math.atan2(dy, dx);
            segment.x = previousX - Math.cos(angle) * segmentSize;
            segment.y = previousY - Math.sin(angle) * segmentSize;
        }else if (Date.now() - lastMouseMoveTime > 300) {
            const head = segments[0];
            const angleToHead = Math.atan2(head.y - segment.y, head.x - segment.x);
            if (index != 0) {
                segment.x += Math.cos(angleToHead) * segmentSize / 2;
                segment.y += Math.sin(angleToHead) * segmentSize / 2;
                segment.element.style.opacity = 0;
            }
        }else {
            if (index != 0){
                segment.element.style.opacity = 1;
            }
        }

        segment.element.style.transform = `translate(${segment.x}px, ${segment.y}px)`;

        previousX = segment.x;
        previousY = segment.y;
    });


    requestAnimationFrame(animateSnake);
}

I tried to debug but I could only see that the value were highlighted, but not changed.

Django is not sending the response with status code 302

Why is Django not sending the response to status code 302?
I see two different codes, 302 and 200. With response ok and redirected: true instead of 302.

I am trying to do a hard redirect to the home page with 302 code.

@csrf_protect
def new_form(request):
    if not request.user.is_authenticated:
        response = HttpResponse(status=302)
        response['Location'] = 'http://192.168.1.200:9000/'
        return response

enter image description here

enter image description here

React – Creating custom filters

I’ve technically created the functionality I want to achieve with a dropdown select field for picking the filter to use for filtering a list of products by category and brand. I’ve built the below snippet so you can see an example of the working code (however I can’t get it to run properly in the code snippet tool although the exact same code is working here in this CodePen I made: https://codepen.io/Chobbit/pen/qBzrPLe)

const {useState, useEffect}  = React

const productDataList = {
  "products": [
    {
      "id": 1,
      "title": "Essence Mascara Lash Princess",
      "category": "beauty",
      "price": 9.99,
      "brand": "Essence",
      "thumbnail": "https://cdn.dummyjson.com/products/images/beauty/Essence%20Mascara%20Lash%20Princess/thumbnail.png"
    },
    {
      "id": 2,
      "title": "Eyeshadow Palette with Mirror",
      "category": "beauty",
      "price": 19.99,
      "brand": "Glamour Beauty",
      "thumbnail": "https://cdn.dummyjson.com/products/images/beauty/Eyeshadow%20Palette%20with%20Mirror/thumbnail.png"
    },
    {
      "id": 3,
      "title": "Powder Canister",
      "category": "beauty",
      "price": 14.99,
      "brand": "Velvet Touch",
      "thumbnail": "https://cdn.dummyjson.com/products/images/beauty/Powder%20Canister/thumbnail.png"
    },
    {
      "id": 4,
      "title": "Dior J'adore",
      "category": "fragrances",
      "price": 89.99,
      "brand": "Dior",
      "thumbnail": "https://cdn.dummyjson.com/products/images/fragrances/Dior%20J'adore/thumbnail.png"
    },
    {
      "id": 5,
      "title": "Dolce Shine Eau de",
      "category": "fragrances",
      "price": 69.99,
      "brand": "Dolce & Gabbana",
      "thumbnail": "https://cdn.dummyjson.com/products/images/fragrances/Dolce%20Shine%20Eau%20de/thumbnail.png"
    },
    {
      "id": 6,
      "title": "Annibale Colombo Sofa",
      "category": "furniture",
      "price": 2499.99,
      "brand": "Annibale Colombo",
      "thumbnail": "https://cdn.dummyjson.com/products/images/furniture/Annibale%20Colombo%20Sofa/thumbnail.png"
    },
  ],
  "total": 194,
  "skip": 0,
  "limit": 36
}

const App = () => {

  const [productsLimit, setProductsLimit] = useState(productDataList.limit)
  const [filterData, setFilterData] = useState(productDataList.products || []);
  const [categories, setCategories] = useState([]);
  const [brands, setBrands] = useState([]);

  useEffect(() => {
    let filteredCategories = [],
        filteredBrands = [];
        productDataList.products.forEach((product) => {
      if (!filteredCategories.includes(product.category)) {
        filteredCategories.push(product.category);
      }
      if (!filteredCategories.includes(product.brand)) {
        filteredBrands.indexOf(product.brand) == -1 && product.brand != '' && product.brand != undefined && product.brand != null ? filteredBrands.push(product.brand) : null;
      }
    });
    setCategories(filteredCategories);
    setBrands(filteredBrands);
  }, []);

  const productFilters = (products, filt) => {
    let filteredProducts = [];
    if (categories.includes(filt)) {
      filteredProducts = products.category.toLowerCase() === filt.toLowerCase();
    } else if (brands.includes(filt)) {
      filteredProducts = products.brand === filt;
    }
    return filteredProducts;
  };

  const filter = (byFilter) => {
    if (byFilter) {
      let productsData = [...productDataList.products];
      productsData = productsData.filter((filter) => {
        return productFilters(filter, byFilter);
      });
      setFilterData(productsData);
    } else {
      setFilterData(productDataList.products);
    }
  };

  return (

    <div>
      <select onChange={(e) => filter(e.target.value)}>
        <option value="Filter Categories" selected="selected">Filter by categories</option>
        {categories.map((catFilter) => (
          console.log(catFilter),
          <option value={catFilter}>{catFilter}</option>
        ))}
      </select>
      <select onChange={(e) => filter(e.target.value)}>
        <option value="Filter Categories" selected="selected">Filter by brands</option>
        {brands.map((item) => (
          console.log(item),
          <option value={item}>{item}</option>
        ))}
      </select>
      <button onClick={filter}>Clear filter</button>
    


      <div className='products'>

        {/* checks the product data exists before mapping it */}
        {filterData?.slice(0, productsLimit).map(product => (
          <div className='product' key={product.id}>
            <div className='productImage'>
              <img src={product.thumbnail} />
            </div>
            <div className='productInfo'>
              <div className='productTitle'>
                <div className='productBrand'>{product.brand}</div> 
                <div className='productName'>{product.title}</div>
              </div>
              <div className='productPrice'>Price: £{product.price}</div>
              {}
            </div>

          </div>
        ))}
      </div>
    </div>
  )
}

// ReactDOM.render(<App />, document.querySelector('#root'));
.products {
    display: flex;
    flex-wrap: wrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>

**

What I want to do now is achieve the same filtering results but using a more visible list of filters a user can click instead of dropdown menus.

**

I’ve tried two methods already, the first was with a function that created an element for each different category/brand option found in the mapped product data json and appended them to filter fields. The second method was just mapping through the category/brand options found in the return() JSX this time. Both methods produce the filter list on the page the way I want them too appear with the filter and the amount of products that filter would return:

Filters appearance on the page

However the problem I’m having is method 1 does nothing on click when I try adding an onClick to each filter created that will call the filter() function. So I feel like I’m not adding this bit correctly onClick=${(e) => filter(e.target.textContent.replace(/s+$/, ''))} to trigger the function when creating the new elements with:

dataFilters.innerHTML = Object.entries(numberOfFilters).map(([mapFilterName,numberFound])=>`<div class="filter"><div class="name" onClick=${(e) => filter(e.target.textContent.replace(/s+$/, ''))}>${mapFilterName} </div> <div class="count"> (${numberFound})</div></div>`).join("n");

The second method when I set it up in the jsx like this:

<div className="catagoryFilters f_rmc f_sb">
  <div className="filterTitle">Categories</div>
  <div className="filtersList">
    {categories.map((filter) => (
      <div className="filter">
        <div className="name" onClick={(e) => filter(e.target.textContent.replace(/s+$/, ''))}>
          {filter} 
        </div> 
        <div className="count"> 
          ({filter.length})
        </div>
      </div>
    ))}
  </div>
</div>

It does try to call the filter() function but all I get is this error message and I don’t understand why?:
Function call error

I’ve tried a few things to get this working this way and despite getting it working using dropdowns, I’m obviously doing something wrong which I’m not quite understanding, to correctly call the filter() function when clicking a filter in the mapped lists.

So any help getting this working and understanding what I’m doing wrong would be greatly appreciated thanks.

Ajax/JavaScript get request to update a HTML element

I am trying to make an empty circle appear when the contents of a GET request are a 0, and a full circle appear when the contents are 1. I am not really sure how to implement this. Needs to poll every 5 seconds or so.

<style>
    .emptycircle {
          border-radius: 50%;
          height: 20px;
          width: 20px;
          border: 2px solid red;
        }
       .fullcircle {
          border-radius: 50%;
          height: 20px;
          width: 20px;
          border: 2px solid red;
          background-color: #f00;
        }       
...
<p id="state" class="emptycircle"></p>
...
<script>
    function getState() {
      $.ajax({
        url: '/state',
        type: 'GET',
        success: function(data) {
          console.log(data);
        }
      });
      if (getState == 0) {
        var state = '.emptycircle';
      } else {
        state = '.fullcircle';
      }
    }
</script>

Currently, invoking getState() from the console returns ‘undefined 0’ or ‘undefined 1’ (with undefined and the number being each on their own line), which is sort of the correct behaviour, so I just need to connect that to the element with id “state” and then have the script run every few seconds.