How to run a line based on user input in Javascript? - javascript

I want to run v-network-graph when the user presses enter, basically, I wrote a function that will create nodes and edges when it runs, once that function runs I want to run the line <v-network-graph #keypress.enter="gr" :nodes='nodes' :edges='edges'/>
I tried writing everything inside the function but it didn't work.
I am new to javascript and Vue, so I'll be grateful for any suggestions.
My template looks like this:
<template>
<div>
<v-network-graph #keypress.enter="gr" :nodes='nodes' :edges='edges'/>
</div>
</template>
My function looks like this:
methods: {
gr() {
const nodes={}
const edges={}
// const { prac } = toRefs(props)
// const n = reactive( prac.value )
// const n= prac.length
const n = this.prac
console.log(n.Organizations)
for (let i = 0; i < n.length; i++) {
nodes[`${n[i].Organizations}`] = {
name: `${n[i].Organizations}`
},
nodes[`${n[i].Title}`] = {
name: `${n[i].Title}`
};
}
for (let i=0;i<n.length;i++){
edges[`edge${i}`]={
source:`${n[i].Organizations}`,
target:`${n[i].Title}`
}
}
console.log(nodes)
console.log(edges)
return { nodes, edges }
}
}

Related

How to break loop in javascript?

const arrow = document.querySelector("#arrow");
const callAllPie = document.querySelector(".allPie");
eventList();
function eventList(e) {
arrow.addEventListener("click", showSkills);
}
function showSkills() {
let element = callAllPie;
for (let i = 0, n = 4; i < n; i++) {
const pie = document.createElement("div");
pie.classList.add("pie1");
callAllPie.appendChild(pie);
const rightDiv = document.createElement("div");
rightDiv.classList.add("slice-right1");
const leftDiv = document.createElement("div");
leftDiv.classList.add("slice-left1");
const percentDiv = document.createElement("div");
percentDiv.classList.add("percent1");
const numberDiv = document.createElement("div");
numberDiv.classList.add("number1");
numberDiv.innerHTML = "%99";
const nameDiv = document.createElement("div");
nameDiv.classList.add("name1");
nameDiv.innerHTML = "HTML";
pie.appendChild(rightDiv);
pie.appendChild(leftDiv);
pie.appendChild(percentDiv);
percentDiv.appendChild(numberDiv);
percentDiv.appendChild(nameDiv);
callAllPie.appendChild(pie);
}
}
I want to break the loop after the click event runs once, how do I do it? When run the click event, added pie div to my page but when I clicked again, it being created again.
You could simply remove the click listener at the beginning of your showSkills() function so no further clicks trigger an action:
function showSkills() {
arrow.removeEventListener('click', showSkills);
let element = callAllPie;
....
}
Or as Teemu points out, a much cleaner approach is to set once: true in the options parameter:
arrow.addEventListener("click", showSkills, {once: true});
You can make a boolean isLoopRunning and use it to see if the loop Is already running
const arrow = document.querySelector("#arrow");
const callAllPie = document.querySelector(".allPie");
eventList();
let isLoopRunning = false;
function eventList(e) {
arrow.addEventListener("click", showSkills);
}
function showSkills() {
let element = callAllPie;
isLoopRunning = !isLoopRunning;
for (let i = 0, n = 4; i < n; i++) {
if (isLoopRunning) {
// your code here
} else {
break;
}
}
}
The break statement terminates the current loop.
if condition satisfies requirement just use break keyword inside loop
for(let i=0; i<10; i++){
if(i==6){
console.log(i)
break;
}
console.log("hi")
}
"hi" will not print after 6 times
When using a status variable outside the function you will have the option to reset the status elsewhere in the code and have the loop run once again.
var showSkills = true;
// Runs once upon user click
function showSkills() {
if (showSkills) {
for {
/* Do the loop */
};
showSkills = false;
};
}
// If you need to run it again upon user click.
// E.g. attach it to some 'reset' button.
function reset() {
showSkills = true;
}

I converted this forEach code to for loop and the code is not working

Clicking the red exit button removes the player from the forEach code, but not for loop.
You click the blue button, next you click the red exit button to remove the player.
How would I get the for loop code to work the same as the forEach code?
This code is working.
https://jsfiddle.net/n1t3kjdw/
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrapper = container.querySelectorAll(".wrap");
wrapper.forEach(function(wrapper) {
if (wrapper.player) {
return removePlayer(wrapper);
}
});
}
What did I do wrong here? https://jsfiddle.net/rbwsL8hf/
Why is this code not working, what needs to be fixed?
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrappers = container.querySelectorAll(".wrap"); {
for (let i = 0; i < wrappers[i].length; i++) {
if (wrappers[i].player) {
return removePlayer(wrappers[i]);
}
}
}
}
In your changed code you have made the iteration condition check for wrappers[i].length instead of what I believe was intended wrappers.length. Otherwise, you are for each iteration checking if i is smaller than the i-th wrapper's length which may or may not be defined.
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrappers = container.querySelectorAll(".wrap"); {
for (let i = 0; i < wrappers[i].length; i++) { // HERE
if (wrappers[i].player) {
return removePlayer(wrappers[i]);
}
}
}
}
Complementing #Salim answer, there is also an extra bracket in your code, try this:
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrappers = container.querySelectorAll(".wrap");
for (let i = 0; i < wrappers.length; i++) {
if (wrappers[i].player) {
return removePlayer(wrappers[i]);
}
}
}

JavasScript Show first two images, and then 1 random images from an array using a class method

I have all of the components for this project with the exception of a class method to show the first two images in the array (the Pokeball, and the default eevee) then randomly choose from an array one more image(eevee evolutions) and then stop.
Please be patient I am very new to this.
class Pokemon {
constructor() {
this.listOfCharmander = [
"./images/pokeball.png",
"./images/charmander/charmander0.png",
"./images/charmander/charmander1.png",
"./images/charmander/charmander2.png",
];
this.index = 0;
this.pokemon = document.createElement("img");
}
handleClick = () => {
if (this.index < 3) {
++this.index;
this.pokemon.src = this.listOfCharmander[this.index];
}
};
buildPokemon = () => {
this.pokemon.src = this.listOfCharmander[0];
this.pokemon.classList.add("pokemon");
this.pokemon.addEventListener("click", this.handleClick);
main.appendChild(this.pokemon);
};
}
const pokemon = new Pokemon();
const pokemon1 = new Pokemon();
pokemon.buildPokemon();
pokemon1.buildPokemon();
class Eevee {
constructor() {
this.eeveeEvolutions = [
"/images/pokeball.png",
"images/eevee/eevee0.png",
"images/eevee/eevee1.png",
"images/eevee/eevee2.png",
"images/eevee/eevee3.png",
"images/eevee/eevee4.png",
"images/eevee/eevee5.png",
"images/eevee/eevee6.png",
"images/eevee/eevee7.png",
"images/eevee/eevee8.png",
];
this.index = 0;
this.eevee = document.createElement("img");
}
handleClick = () => {
if (this.index < 9) {
++this.index;
this.eevee.src = this.eeveeEvolutions[this.index];
}
};
buildEevee = () => {
this.eevee.src = this.eeveeEvolutions[0];
this.eevee.classList.add("eevee");
this.eevee.addEventListener("click", this.handleClick);
main.appendChild(this.eevee);
};
}
const eevee = new Eevee();
const eevee1 = new Eevee();
eevee.buildEevee();
eevee1.buildEevee();
...
I apologize if my question isnt exactly clear. I need to add to my handClick method. A way display the first image (the Pokeball) and then the 2nd image (default eevee) And then randomly choose (including having it stay the same there could be no evolution at all) one more evolution from the remaining array.
if you always need first two images in your array then you can add extra attribute to your Eevee class to store those images path, and for random image you can add this code to your handleClick()
handleClick = () => {
this.index=Math.floor(Math.random(2,9)*10)
this.eevee.src = this.eeveeEvolutions[this.index];
};

Module - IIFE isn't automatically called

I created a module but it is not automatically rendered in my page, I have to manually call Board.renderBoard() in the console for the Board to appear. What am I doing wrong ?
here's the entire code:
const Board = (() => {
const board = document.querySelector('.board');
const createTiles = () => {
tile = document.createElement('div');
tile.classList.add('tile');
return tile;
};
const renderBoard = () => {
for (let i = 0; i < 9; i++) {
createTiles();
board.appendChild(createTiles());
}
};
return {
renderBoard
};
})();
I created a module but it is not automatically rendered in my page, I have to manually call Board.renderBoard() in the console for the Board to appear.
JS doesn't just call function unless you tell it to call these functions.
Your module simply defines an object Board with a method renderboard. There's nothing that tells JS to call this method.
You could add the call right after declaring the module.
const Board = (() => {
...
})();
Board.renderBoard();
But if all you want is that the code initially builds the board you can do:
(() => {
const board = document.querySelector('.board');
const createTiles = () => {
const tile = document.createElement('div'); // please declare your variables
tile.classList.add('tile');
return tile;
};
for (let i = 0; i < 9; i++) {
createTiles(); // what is this line for?
board.appendChild(createTiles());
}
})();
or
(() => {
const board = document.querySelector('.board');
for (let i = 0; i < 9; i++) {
const tile = document.createElement('div');
tile.classList.add('tile');
board.appendChild(tile);
}
})();
or maybe even
document.querySelector('.board').innerHTML = '<div class="tile"></div>'.repeat(9);

Binding event listeners multiple times in JavaScript

I'm trying to get the directory list, level by level, using JavaScript.
I have this paths array as input.
var _paths = [];
_paths.push("meta1/meta2/test/home/myself/hi.jpg");
_paths.push("meta1/meta2/test/home/myself/hi1.jpg");
_paths.push("meta1/meta2/test/home/myself/hi2.jpg");
_paths.push("meta1/meta2/test/work/she/100.jpg");
_paths.push("meta1/meta2/test/work/she/110.jpg");
_paths.push("meta1/meta2/test/work/she/120.jpg");
_paths.push("meta1/meta2/test/work/hard/soft/she/120.jpg");
_paths.push("meta1/meta2/test/work/hard/soft/she/121.jpg");
_paths.push("meta1/meta2/test/work/she/220.jpg");
and I want to have a "test" as output, which will be clickable. After click "test", it should be replaced by "home" and "work". After click on "home" - "myself", on "work" - "hard" and "she".
I wrote this:
CodepenCode
and it works only once, only when clicking on "test".
Simply rebind the listeners after the directories have been drawn. You bind them only once, thus they work only once.
Wrap the binding function into a named function:
function bindListeners(){
$('.sub').click(function() {
word = $(this).text();
filteredArr = findString(_paths, word);
drawList(filteredArr, word);
});
}
And call it at the end of drawList:
var drawList = function (paths, word) {
var folders = getFolders(paths, word);
if (folders.length > 0) {
$('.canvas').html('');
for (i = 0; i < folders.length; i++) {
$('.canvas').append("<div class='sub'>" + folders[i] + "</div><br />");
}
}
bindListeners();
}
Demo.
If anyone is curious about building out the data structure:
(function iteratePaths() {
var dirs = [];
for(var i = 0; i < _paths.length; i++) {
buildDirectories(dirs, _paths[i].split('/'));
}
})();
function findDir(dir, obj) {
for(var i = 0; i < dir.length; i++) {
if(dir[i].name === obj.name) {
return dir[i];
}
}
return undefined;
}
function buildDirectories(dir, subs) {
if(subs.length === 0) return;
var obj = {name: subs.shift(), dirs: []};
var existingDir = findDir(dir, obj);
if(!existingDir) {
dir.push(obj);
}
buildDirectories((existingDir || obj).dirs, subs);
}

Categories