When I click on my useNavigate it reloads my page and wipes the state i gave it. How do i prevent this

I have a page that has a pediatric and a adult version to access these i have two buttons that link to the same page but just i send a different state so I can load the page depending on what state it was previously sent. The problem is my pediatric navigate reloads the page on button press and causes the the location.state to be null

    const handleNavigate = (e) => { console.log(algorithms[e]); navigate('/medical/aha-algorithms/algorithms', {state: {...algorithms[e]}}) }
    
    return(
        <div className='homepage-container'>
            <Grid2 item xs={12} md={4} sx={{width: '100%'}}>
                <Grid2 item xs={12} md={4} sx={{width: '100%'}}>
                    <Card 
                        sx={pageButtons}
                        onClick={() => handleNavigate('pediatric')}
                    >
                        <CardContent sx={buttonConent}>
                            <Typography variant="h6" sx={{textAlign: 'center', color: 'white'}} mb={2}>PEDIATRIC</Typography>
                        </CardContent>
                    </Card>
                </Grid2>
                <Grid2 item xs={12} md={4} sx={{width: '100%'}}>
                    <Card 
                        sx={pageButtons}
                        onClick={() => handleNavigate('adult')}
                    >
                        <CardContent sx={buttonConent}>
                            <Typography variant="h6" sx={{textAlign: 'center', color: 'white'}} mb={2}>ADULT</Typography>
                        </CardContent>
                    </Card>
                </Grid2>
            </Grid2>
        </div>
    )

i was expecting the above on both button presses to show the page at /medical/aha-algorithms/algorithms and have a state for each item

here is the code from the algorithms page

export default function Algorithms() {
    const location = useLocation(); 
    console.log(location)

    const navigate = useNavigate() // to move to the page with specific pdfs in it 
    return(
        <h1>Algorithms</h1>
    )
}

Any way to both pass form data and fun a fetch command with the same button press?

I might be going about this entirely the wrong way, but I’m working off of whatever tutorials I can find and am still getting acquainted with javascript, so I may very well have missed something obvious. I’ve tried everything I can think of and I’m completely out of ideas. I will detail what I’ve tried below. First, the problem:

I have a form, and I am trying to:

  1. Pass the contents of the form to a php script, which does some processing and then amends it to an html file, feed.html, then
  2. update a div to reflect the contents of feed.html, without having to completely refresh the page.

Here is the form and the div I want to update:

<div id="feed"></div>

<form onsubmit="return sendData()" id="tincan">
  <textarea id="shoutAperture" name="shoutAperture"></textarea>
  <!--<input type="submit" id="shout" name="shout" value="SHOUT">-->
  <button id="shout" name="shout">SHOUT</button>
</form>

(I have also tried it with <input type="submit"> instead of a button in case that made any difference, thus the commented-out code.)

Here are the scripts I have, which so far just collect the contents of the textarea and pass them to shout.php:

async function summonFeed() {
  let file = "feed.html";
  let summons = await fetch(file);
  let feed = await summons.text();
  document.getElementById("feed").innerHTML = feed;
}
summonFeed();

function sendData() {
  let data = new FormData(document.getElementById("tincan"));
  fetch("shout.php", {
    method: "POST",
    body: data,
  });
  return false;
}

It successfully passes the form data to my php script and, from there, to feed.html, and when there is text in the feed.html file it does successfully show up on page load, but I can’t get it to refresh dynamically. So far, no matter what I’ve tried, I have only been able to get the “feed” div to update upon hard refreshing the page (control-clicking the refresh button in Firefox; it does nothing when I simply click refresh). I have tried:

  • calling multiple functions in form onsubmit (I tried separating them with &, &&, ,, and ; as indicated by various decade-old forum threads). This usually made it update the url in the address bar instead of actually passing my data to the php script.
  • adding a .then command to function sendData () either calling the summonFeed script or just wholesale repeating all of its code. (Nothing happens.) (I admit I don’t think I’ve fully grasped the mechanics of .then, despite my best efforts.)
  • creating a third function which runs sendData and summonFeed, and calling that from the form instead of sendData. (Nothing happens, or it just updates the url instead of passing the data to my php file.)
  • creating a separate onClick function that just runs summonFeed again when the button is pressed (It still calls the old version of the file from before the php script updated it; when I hard refresh the page the changes appear.)

I think that’s all I tried, but I have been at this for hours and may have forgotten some things. Any suggestions would be deeply appreciated!

How do I append an image after clicking a button and remove it on every other click in a container within JS?

I’m trying to create a mushroom log where a container populates with a unique group of images after pressing different buttons.

An image appears after clicking the first button, but it doesn’t go away after clicking again. What do I need to change in order for the image to disappear on every other click or on other button clicks?

HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mushroom Log</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <h1>Mushroom Log</h1>
    <br>
    <section id="container"></section>
    <h2>Select a Mushroom Type</h2>
    <br>
    <button type="button" class="button1">Light-Spored Gilled Mushrooms</button>
    <button type="button" class="button2">Brown-Spored Gilled Mushrooms</button>
    <button type="button" class="button3">Dark-Spored Gilled Mushrooms</button>
    <button type="button" class="button4">Polypores and Crust-Fungi</button>
    <button type="button" class="button5">Puffballs, Earthballs, and Earthstars</button>
    <button type="button" class="button6">Jelly-like Fungi</button>
</body>
<script src="app.js"></script>

</html>

Javascript:

const btn1 = document.querySelector('.button1');

function lightSpored() {
    let beenCalled = false;
    if (!beenCalled) {
        beenCalled = true;
        btn1.addEventListener('click', () => { container.append(fungi1) });
    } else {
        container.innerHTML = ' ';
        beenCalled = false;
    }
}

lightSpored();

Android Webview Pass Data using HTML Tag

I have a webview inside one of my android fragments.

When I type some text in my android fragment and click a button on a the android fragment, I am able to set an Webview tag’s .value or .innerhtml to that text using Android webView.evaluateJavascript(see below).

And looking at the web view, it I can confirm visually see setting the .value or setting the .innerhtml is working.

However, after these are done, I want to fire some of my webview’s code to read that .value or .innerhtml text and do some operation with it. However, it seems like the web view does not find any data in the .value or .innerhtml.

Does anyone know why it is not updating?

Sample code on android side:

        binding.webview.evaluateJavascript(
            "document.getElementById('test-target').innerHTML='$message';"
             + "document.getElementsByClassName('send-button')[0].click()"
                ){} 

Pseudo code on web view side:

  1. On the send-button onClickListner, I want to read the ‘test-target’.innerhtml and do an operation with it. But it does not find anything, even when I have visually verified that the .innerHTML has been set by the android code from evaluateJavascript().

On Scroll Text – When page is reloaded is causing a big shift(jump)

I am trying to create a marquee text that moves when the page is scrolled, at the moment I am getting the functionality but for e.g if I reload the page at a certain position the text is shifting(jumping) too much giving a not so desirable effect.
This is the codepen link : https://codepen.io/endritibra-the-flexboxer/pen/xxyZJbb
This is the code:

<div class="marqueeContainer">

  <div class="marqueeText">
    <h1>Endrit</h1>
    <h1>As</h1>
  </div>
  <div class="marqueeText">
    <h1>Artan</h1>
  </div>
  
  
</div>

<div class="container">
  <h2>Hahahahahah</h2>
  <h2>Hahahahahah</h2>  
<h2>Hahahahahah</h2>  
<h2>Hahahahahah</h2> 
 <h2>Hahahahahah</h2>
  <h2>Hahahahahah</h2> 
 <h2>Hahahahahah</h2>
  <h2>Hahahahahah</h2> 
 <h2>Hahahahahah</h2>
  <h2>Hahahahahah</h2>
  <h2>Hahahahahah</h2>
</div>
<div class="marqueeContainer">
  <div class="marqueeText">
    <h1>Endrit</h1>
    <h1>As</h1>
  </div>
  <div class="marqueeText">
    <h1>Artan</h1>
  </div>
  
  
</div>
.marqueeContainer{
  display:inline-flex;
  width:100%;
  overflow:hidden;
}

.marqueeText{
  min-width:100%;
  display:inline-flex;
}

.marqueeText *{
  margin:0 1rem;
}
const marqueeContainer=document.querySelectorAll(".marqueeContainer");
const marqueeText=document.querySelectorAll(".marqueeText");

document.addEventListener('scroll',()=>{

marqueeContainer.forEach((item)=>{
  
  
              window.requestAnimationFrame(() => {

  
  function animate(itm,calcSpeed){
                    itm.style.transform = `translateX(${calcSpeed}px)`;

  }
  let itemsrc=item.getBoundingClientRect().y;
                console.log(itemsrc)
  marqueeText.forEach((itms)=>{
      animate(itms,itemsrc)

  })
  
})
})
  
})

The functionality is there, I mean when I scroll with mouse the text moves but if I want to reload the page and I am in certain position on the page if then I scroll the text jumps a lot, giving a bad effect.“

Does setting a javascript variable with an OR work similar to an if?

I’m studying recursion, and I came across an example of using the Fibonacci sequence and it talked about the concept of memoization. In that, it has a variable that is declared with an OR (||). I’m a little confused by that.

Here is the code:

fib = (number, storage) => {
    storage = storage || {}; //<--This is what I'm asking about

    if (storage[number]){
        return storage[number];
    } 
    if (number <= 1){ //<--second question 
        return 1;
    } 
    return storage[number] = fib(number -1, storage) + fib(number-2, storage);
}

Is my understanding correct that when this is called the first time, it assigns an empty object to storage, since storage isn’t passed in the first time, and doesn’t yet exist? Then on subsequent calls, since storage is something (an object), it just goes with the first option and assigns storage and ignores the OR?
Also, separate question, but as this function doesn’t explicitly stop at 0, why does it in fact stop at zero? Why doesn’t it just continue indefinitely into negative numbers?

adding three.js to phoenix live view project

I’m trying to add three.js as a dependency to my Phoenix Project.

At the moment, I’ve vendored a minified three.js version in /assets/vendor/three.min.js

From there I added the following to my app.js:

import * as THREE from "../vendor/three.min.js";

window.THREE = THREE;

let Hooks = {};
Hooks.ThreeInit = {
  mounted() {
    if (this.el.dataset.initialized === "false") {
      this.initThreeScene();
      this.el.dataset.initialized = "true";
    }
  },
  initThreeScene() {
    // Initialize your three.js scene here, using `THREE` object.
    // For example:
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer();

    renderer.setSize(window.innerWidth, window.innerHeight);
    this.el.appendChild(renderer.domElement);

    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    const cube = new THREE.Mesh(geometry, material);

    scene.add(cube);
    camera.position.z = 5;

    const animate = function () {
      requestAnimationFrame(animate);

      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;

      renderer.render(scene, camera);
    };

    animate();
  }
};

// other alpine stuff here

let liveSocket = new LiveSocket("/live", Socket, {
  params: {_csrf_token: csrfToken},
  hooks: Hooks,
  dom: {
    onBeforeElUpdated(from, to) {
      if (from._x_dataStack) {
        window.Alpine.clone(from, to)
      }
    }
  }
})

// connect if there are any LiveViews on the page
liveSocket.connect()

The live view I am trying to render the 3D cube over is as follows:

defmodule PortfolioWeb.ThreeJSLive do
  use Phoenix.LiveView

  def mount(_params, _session, socket) do
    {:ok, socket}
  end



  def render(assigns) do
    ~L"""
    <h1>Hello, World!</h1>
    <div id="three-container" phx-hook="ThreeInit"></div>
    """
  end
end

At the moment, the only thing that renders is the Hello World

Any help in figuring out what the issue is would be greatly appreciated <3

How to resolve a an Object Promise in this

I cannot get a value to output in :value="myFunction(cur_path)" no matter what. It’s always an object Promise even though I’ve tried different ways to await the value from the async function. async fetch_dpids(x) gets data from the API, I call that function in another function called async myFunction(x) to await the value and output it through :value="" in the Vue HTML tags.

  <k-accordion>
    <k-accordion-item title="Best Paths">
        <div>
          <k-property-panel v-for="(path, index) in content">
            <k-accordion-item :title=format_title(index,path['cost'])>
              <k-property-panel-item v-for="(cur_path, path_index) in path['hops']"
                                     v-if="content" :name="String(path_index)" :value="myFunction(fetch_dpids, cur_path)" :key="path_index">
              </k-property-panel-item>
            </k-accordion-item>
          </k-property-panel>
        </div>
      </k-accordion-item>
  </k-accordion>
</template>
<!-- :name="String(path_index)" holds the # count;  
      :value="cur_path" holds the switch/interface; e.g. 00:00:00:00:00:00:00:03
      -->
<script>
 module.exports = {
   props: ["content"],
   methods: {
    format_title(index, cost){
      return "Path " + index + ", cost: " + cost + ", hops: ";
    },
    
    async fetch_dpids(x) {
      try {
          const response  = await fetch('/api/myAPI/topology/v3/interfaces');
          const data      = await response.json();
          const dpids = Object.entries(data.interfaces).map(([key, value]) => {
            let item = key;
            if (item == x) { // troubleshooting
                console.log(item + "HERE <-------");
              }
            if (value.name) {
              item = `${value.name} - ${item} - ${value.mac}`;
            }
            return item;
          });
          this.dpids = dpids;
      } catch (error) {
          console.error(error);
      }
    },
    async myFunction(fetch_dpids, x) { //recent addition
      const result = await fetch_dpids(x);
      return result; // logs the resolved value of the Promise
  }
   }, // end of method block here
    
   data () {
     return {
       display: false,
       paths: [],
       headers: ["dpid"],
       rows: [this.content]
     }
   }
   
 }


</script>```

[Console log][1]
[object Promise][2]


  [1]: https://i.stack.imgur.com/OpX7r.png
  [2]: https://i.stack.imgur.com/msDgV.png

How to prevent v-model from being truth/false in an input checkbox (vue)

I currently am creating a filter popup with a list of checkboxes. On default, there should be some items selected and some not selected. I have these checkboxes connected to an object array using v-model. My problem is that when I deselect and select an item, instead of passing the object value it passes in true/false. My code is below:

<template>
    <v-card>
        <v-card-title>
            <span class="headline">Filter Headers</span>
        </v-card-title>
        <v-card-text>
            <div class="column" v-for="(header, index) in allHeaders" :key="index">
                <input
                v-model="filteredHeaders[index]"
                type="checkbox"
                :id="index"
                >
                <label :for="index"
                >{{ header.text }}</label>
            </div>
            <p class="ml-5 mt-10"> {{ filteredHeaders }} </p>

        </v-card-text>

    </v-card>    
</template>

<script>
    export default {

        props: {
            headers: Array,
            allHeaders: Array,
        },
        computed: {
            updatedTitleOnly() {
                var titleOnly = [];
                var objectPlaceholder = {};
                console.log(this.filteredHeaders);
                    if(this.filteredHeaders.length > 0) {
                        for(var i = 0; i < this.filteredHeaders.length; i++) {
                            objectPlaceholder = this.filteredHeaders[i];
                            console.log(objectPlaceholder);

                            // titleOnly.push(objectPlaceholder.text)
                        }
                }
                    return titleOnly;
            }
        },
        data() {
            return {
                updateCheck: [],
                filteredHeaders: this.headers,
            }
        },

    };
</script>

<style>
    .column {
        display: inline-block;
        width: 50%;
        box-sizing: border-box;
        padding: 0 10px;
    }
</style>

As you can see, I use a prop called allHeaders to get the list of all possible headers. Then I use a for-loop to create a checkbox for each header and assign the value of each checkbox to a value in a new array called filteredHeaders. What I want is to have these checkboxes determine what values go inside filteredHeaders. With my current code, the values get removed properly, but when I try to add them back instead of adding that object value, I get “true” or “false”.

I am not sure what to do next.

[gruntjs]How to update ES6 import statements in uglify section of Gruntfile.js

module.exports = function(grunt){
grunt.initConfig({

uglify: {
            'minify-each':{ 
                options : {
                    beautify: false, 
                    mangle: false,  
                    sourceMap: true,
                    compress: {
                        drop_console: true 
                    }
                },
                files: [{
                    cwd: 'src/private/assets/js/',
                    src: '**/*.js',
                    dest: 'src/public/assets/js/',
                    expand: true,
                    flatten: false,
                    ext: '.min.js' //Extension not used in ES6 import statements
                }]
            }

});

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('run', ['uglify']);

};

In each *.js file, there are ES6 import statements, for example:

in file1.js, I have…

import { getConstants, getUtils } from ‘../assets/js/utils.js’;
import { WidgetClass } from ‘../assets/js/classes.js’;

class ProcessMain {}

The issue is when performing minification on file1.js in Gruntfile.js, those import statements are maintained, but do want to be able to replace each import statement as follows:

import { getConstants, getUtils } from ‘../assets/js/utils.min.js’;
import { WidgetClass } from ‘../assets/js/classes.min.js’;

Are there ways to capture each line in file1.js to update the import statements?

Within uglify object in Gruntfile.js, I have replaced:

ext: ‘.min.js’ //Extension not used in ES6 import statements
–with–
ext: ‘.js’ //Extension used in ES6 import statements

and that seems to do the trick, perhaps, resolves the issue. However, it is not standard since the minified file1.js does not have a *.min.js extension.

Can we replace jQuery iframe creation with native Javascript way? [duplicate]

Background: jQuery version 2.1.3 (https://code.jquery.com/jquery-2.1.3.js) has following snippet:

iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );

Can I replace it with following code (from your example)

if ( !iframe ) {
 iframe = document.createElement( "iframe" );
 iframe.frameBorder = iframe.width = iframe.height = 0;
}
doc.documentElement.appendChild( iframe );

The purpose is very strange, in short, web firewall’s stupid rule is preventing jQuery code to be executed saying that this is an iframe injection.

Will the snippet serve the original purpose?

Please let me know.

Thank you.

I tried upgrading jQuery but it’s breaking other dependencies.

How do I generate all variations when only one letter is enclosed in parentheses?

The code should generate all variations of a word that have letters in parentheses. Currently, it works when there are multiple letters in the parentheses, but not when there is only one letter inside.

Example:
t(ea)st

test, tast

Here, “test” and “tast” are generated from the word “t(ea)st”. That works fine.

But what doesn’t work is when there is only one letter in the parentheses.

Example:
t(e)st

test

Only the word “test” is generated, but it should also generate “tst”.
The problem now is that no matter what I try, I can’t get it to generate the word “tst”.

If there are multiple parentheses with only one letter inside, as in this example:

t(e)st(s) – then the following words should be generated:

tests, test, tsts, tst

  const generateVariations = (() => {
    const cache = {};

    return (word) => {
      if (cache[word]) {
        return cache[word];
      }

      const variations = [];

      // Find all groups of letters in parentheses
      const groups = word.match(/(([^)]+))/g) || [];

      // Create an array of arrays, where each subarray contains the letters in a group
      const letterArrays = groups.map(group => group.slice(1, -1).split(''));

      // If a group has only one letter, remove the parentheses and add the letter to the list of groups
      const modifiedGroups = groups.reduce((acc, group) => {
        if (group.length === 3) {
          acc.push(group[1]);
        } else {
          acc.push(group);
        }
        return acc;
      }, []);

      // Generate all possible combinations of letters from each group
      const combinations = cartesianProduct(...letterArrays);

      // Generate variations by replacing each group with each combination of letters from that group
      for (const combination of combinations) {
        let newWord = word;
        for (let i = 0; i < modifiedGroups.length; i++) {
          const group = modifiedGroups[i];
          if (group.length === 1) {
            newWord = newWord.replace(`(${group})`, group);
          } else {
            newWord = newWord.replace(groups[i], combination[i]);
          }
        }
        variations.push(newWord);
      }

      cache[word] = variations;
      return variations;
    };
  })();

  function cartesianProduct(...arrays) {
    let result = [[]];
    for (const array of arrays) {
      const newResult = [];
      for (const x of result) {
        for (const y of array) {
          newResult.push([...x, y]);
        }
      }
      result = newResult;
    }
    return result;
  }

Why is the code after my for loop not running?


<script>
    
    //references the submit button, runs if it is clicked
    const sub = document.getElementById("sub");
    sub.addEventListener("click", (e) => {
    e.preventDefault();
    
    //references every input number
    var in1 = document.getElementById("in1").value;
    var in2 = document.getElementById("in2").value;
    var in3 = document.getElementById("in3").value;
    var in4 = document.getElementById("in4").value;
    var in5 = document.getElementById("in5").value;
    
    //creates an array and puts all of the inputted values into it
    const inputs = new Array();
    inputs.push(in1, in2, in3, in4, in5);
    
    //references all of the circles
    var num1 = document.getElementById("num1");
    var num2 = document.getElementById("num2");
    var num3 = document.getElementById("num3");
    var num4 = document.getElementById("num4");
    var num5 = document.getElementById("num5");
    
    //creates an array and stores all of the references to the circles in it
    var circles = new Array();
    circles.push(num1, num2, num3, num4, num5);
    
    //creates an array for the generated numbers
    var generated = new Array();
    
    for(i = 0; i < 6; i++){
        //fills the array with 5 random numbers
        let gen = Math.round(Math.random() * 38);
        generated.push(gen);
        //changes the numbers in the circles to the random numbers
        circles[i].innerHTML = generated[i];
    
    }
    
    alert("test");//this doesn't pop up
    
    });

All of my code up to this point works perfectly, and the numbers are correctly added to the circles, but then anything I write after the for loop does not run, and I cannot figure out why. If the alert is anywhere else in the code above the for loop, it pops up with no issues.
Any help is greatly appreciated.

I tried to make an alert pop up to check if anything was running after the for loop, and it did not pop up.

How can I implement a button click event listener that will survive DOM updates (ie. in a single-page application) [duplicate]

I am writing a ViolentMonkey userscript that will add an event listener on a button #mark-watched, so that when it is clicked, the #next-video button will be clicked automatically. The website doesn’t automatically mark the video as watched or automatically navigate to the next video upon completion so this is the purpose of the userscript.

The following is a simplified outline of the webpage on which my userscript will run

  <div class="container">
    <button id="next-video" type="button">Next Video</button>
    <button id="mark-watched" type="button">Complete section</button>
  </div>

Here is the userscript I’ve written:

  const mark_watched_btn = document.getElementById("mark-watched");
  const next_video_btn = document.getElementById("next-video");

  mark_watched_btn.addEventListener("click", (event) => {
    // wait an arbitrary 500ms to allow the page to submit its AJAX call marking the video as watched
    setTimeout(() => {
      next_video_btn.click();
    }, 500);
  });

The userscript works properly when the page is first loaded, but when the page navigates to the next video, the event listener I implemented will no longer work because the website is running via some javascript SAP framework, so when the entire .container component is reloaded and a new set of buttons are placed, the userscript (or ViolentMonkey) does not re-run the userscript.

Is there a way to have my click event listener on #mark-watched be applied to any and all future buttons that may appear on the page?