Input value does not replace global scope. I'm trying to have a default number on a variable. I would like to enter a number into an input on the browser and then update that variable.
// VARIABLES
const container = document.querySelector('.container');
const unsplashURL = 'https://source.unsplash.com/random/';
let rows = 3
const input = document.querySelector('#number')
const button = document.querySelector('.button')
for (let i = 0; i < rows * 3; i++) {
const img = document.createElement('img')
img.src = `${ unsplashURL }${ getRandomSize() }`
container.appendChild(img)
}
button.addEventListener('click', (e) => {
e.preventDefault()
let rows = input.value
input.value = ''
})
// FUNCTIONS
function getRandomSize() {
return `${ getRandomNr() }x${ getRandomNr() }`
}
function getRandomNr() {
return Math.floor(Math.random() * 11) + 300
}
#phil_Hinch, here are the problems you have.
JavaScript code is not re-running automatically. You need to define function like setupGrid and call this function every time after you update rows.
On button click listener, you wrote let rows = input.value. Which means new variable rows declared for that code block. This will not update let rows = 3. You need to remove let to update global rows.
Please check following example
// VARIABLES
const container = document.querySelector('.container');
const unsplashURL = 'https://source.unsplash.com/random/';
let rows = 3
const input = document.querySelector('#number')
const button = document.querySelector('.button')
function setupGrid() {
container.innerHTML = ''
for (let i = 0; i < rows * 3; i++) {
const img = document.createElement('img')
img.src = `${ unsplashURL }${ getRandomSize() }`
container.appendChild(img)
}
}
button.addEventListener('click', (e) => {
e.preventDefault()
rows = input.value
input.value = ''
setupGrid()
})
// FUNCTIONS
function getRandomSize() {
return `${ getRandomNr() }x${ getRandomNr() }`
}
function getRandomNr() {
return Math.floor(Math.random() * 11) + 300
}
setupGrid();
.container {
width: 100%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 1rem;
}
.container img {
width: 80%;
}
<div class="container">
</div>
<input id="number" type="number" />
<button class="button">update</button>
Related
I have a simple HTML document of three pictures like this-
Now I need to modify the code so that the deleting of images
starts from the beginning, reload the page, and the result like-
Here is code:
export default () => {
const button = document.querySelector('#b1');
const listener = e => {
const images = document.getElementsByTagName('img');
// for(let i = 0; i <= images.length; i++) {
for(let i = images.length - 1; i >= 0; i--) {
const image = images[i];
if(image.alt) {
let text = document.createTextNode(image.alt);
image.parentNode.replaceChild(text, image);
}
}
const style = `
color: yellow;
border: 2px solid yellow;
`;
button.setAttribute('style', style);
button.style.backgroundColor = 'red';
button.disabled = true;
button.textContent = 'Disabled';
};
// button.onclick = listener;
button.addEventListener('click', listener);
};
Does anybody know what to do?
I tried
for(let i = images.length - 1; i >= 0; **i=i-2**) {
const image = images[i];
if(image.alt) {
let text = document.createTextNode(image.alt);
image.parentNode.replaceChild(text, image);
}
}
And I get the desired look(like in the resulting picture), but I need to reload the page and get the output as shown in the resulting picture.
Need help!
simply put I am creating a grid that is x * x. the "x" variable is going to be whatever the user inputs.
Where I am struggling is I need be able to click a button and have a prompt widow come up, collect the number the user enters, and then use that number as an argument for a function I created to build the grid.
As you can probably tell by my question, I am fairly new to coding. So the simpler the solution the better for me to understand.
Thanks a ton!
const div = document.querySelector('#container')
const clearButton = document.querySelector('.button-clear');
const resizeButton = document.querySelector('.button-resize')
createGrid = gridNumber => {
if (gridNumber === undefined) {
gridNumber = 16;
} else gridNumber = gridNumber;
let gridSize = gridNumber * gridNumber;
for (i = 0; i < gridSize; i++) {
let squares = document.createElement('div');
squares.classList.add('squares');
div.style.gridTemplateRows = `repeat(${gridNumber}, 1fr)`;
div.style.gridTemplateColumns = `repeat(${gridNumber}, 1fr)`;
div.appendChild(squares);
}
let boxes = document.querySelectorAll('.squares');
boxes.forEach(box => box.addEventListener('mouseover', () => {
box.style.backgroundColor = "gray";
}));
}
resetGrid = () => {
let boxes = document.querySelectorAll('.squares');
boxes.forEach(box => {
box.style.backgroundColor = 'white';
})
}
createGrid();
clearButton.addEventListener('click', resetGrid);
Just prompt for the value and call the function again. Check for undefined in case user didn't enter anything.
const div = document.querySelector('#container')
const clearButton = document.querySelector('.button-clear');
const resizeButton = document.querySelector('.button-resize')
createGrid = gridNumber => {
if (gridNumber === undefined) {
gridNumber = 16;
} else gridNumber = gridNumber;
let gridSize = gridNumber * gridNumber;
for (i = 0; i < gridSize; i++) {
let squares = document.createElement('div');
squares.classList.add('squares');
div.style.gridTemplateRows = `repeat(${gridNumber}, 1fr)`;
div.style.gridTemplateColumns = `repeat(${gridNumber}, 1fr)`;
div.appendChild(squares);
}
let boxes = document.querySelectorAll('.squares');
boxes.forEach(box => box.addEventListener('mouseover', () => {
box.style.backgroundColor = "gray";
}));
}
resetGrid = () => {
let boxes = document.querySelectorAll('.squares');
boxes.forEach(box => {
box.style.backgroundColor = 'white';
})
}
createGrid(4);
clearButton.addEventListener('click', resetGrid);
resizeButton.addEventListener('click', function() {
var value = prompt("enter size: ", 16);
if (typeof value === 'undefined') {
return
}
createGrid(value)
});
.squares {
border: 1px solid black;
width: 20px;
height: 20px;
float: left;
}
<div id="container">
</div>
<button class="button-clear">clear</button>
<button class="button-resize">resize</button>
My Problem
I would like some help understanding how to increase the label const label = document.createElement("label"), which would start at 1 and increase with every new row added.
This section of code is the addEventListener for the button
document.querySelector('button').addEventListener('click', renderRow())
This section of code renders the row when the button is clicked
function renderRow() {
const row = document.createElement('div');
const label = document.createElement("label");
const input1 = document.createElement("input");
input1.type = "number";
const input2 = document.createElement("input");
input2.type = "number";
const result = document.createElement("div");
row.append(label, input1, input2, result);
There are many ways you can achieve this. Here is a small, modified excerpt of your code as an example with some explanation comments.
The basic idea of this approach is to render elements based on a dynamic state which in this case is just a counter that controls how many children are rendered at a given moment. The add and delete buttons control this counter and call the render function to reflect the updated state of the counter in the view.
// define a static starting number if needed
const startingNum = 5;
// define dynamic counter
let counter = 0;
// get ref of parent rows container
const divBox1 = document.querySelector(".fifth-row");
// increase counter when add button is clicked and render rows
document.querySelector('button')
.addEventListener('click', function () {
counter += 1;
renderRows();
});
// decrease counter when any of the delete buttons is clicked and render rows again
divBox1
.addEventListener('click', function (e) {
if (e.target.classList.contains('deleteBtn')) {
counter -= 1;
renderRows();
}
});
// render rows based on the state of the counter
function renderRows() {
// calc total number of rows to render based on current counter value
const total = (startingNum + counter) - startingNum;
// clear container by removing children
divBox1.innerHTML = '';
// render rows
for (let i = 0; i < total; i++) {
addRow(startingNum + i);
}
}
function addRow(rowNumber) {
// create a container for each row
const rowContainer = document.createElement('div');
rowContainer.classList.add('row-container');
divBox1.appendChild(rowContainer);
const labelBox = document.createElement("LABEL");
rowContainer.appendChild(labelBox);
labelBox.classList.add('labelBet');
// set the text content including the dynamic row number
labelBox.textContent = "Bet " + rowNumber;
const inputBox = document.createElement("INPUT");
rowContainer.appendChild(inputBox);
inputBox.classList.add('oddsEntry');
const divBox2 = document.createElement("DIV");
rowContainer.appendChild(divBox2);
divBox2.classList.add('stakePreTotal');
const divBox3 = document.createElement("DIV");
rowContainer.appendChild(divBox3);
divBox3.classList.add('liaDiv');
const btnDel = document.createElement("BUTTON");
btnDel.innerText = 'Delete';
rowContainer.appendChild(btnDel);
btnDel.classList.add('deleteBtn');
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
button {
padding: .3rem .5rem;
}
.rows > div.fifth-row > div {
display: flex;
}
<div class="rows">
<div class="fifth-row"></div>
</div>
<button type="button">add row</button>
let body = document.querySelector("body");
let container = document.querySelector("#container");
//Accessing HTML Elements
let inputArray = [];
for (let element = 0; element < 30; element++) {
space = document.createElement("input");
container.appendChild(space);
space.setAttribute("id", element);
space.classList.add("square");
inputArray.push(space);
}
//For loop that creates a grid of squares and adds each square to an array
document.onkeydown = event => {
if (event.keyCode === 37) {
for (let i = 0; i < 31; i++) {
inputArray[i].value = "";
}
}
}
//When the left arrow key is pressed, the text in every square disappears
I do not see the problem. (Apart from the error Uncaught TypeError: Cannot set properties of undefined (setting 'value') : you using loop i<31 to the clear, but you only use i<30 to the create).
And a little mistake: you do not define the space variable (I recommend to use let).
If I understood your question correctly?
const container = document.querySelector('#container')
const inputArray = Array.from(({length:30}),(e,i)=>
{
let space = container.appendChild( document.createElement('input') )
space.id =
space.placeholder = i
space.className = 'square'
})
container.onkeydown = evt =>
{
if (evt.key === 'ArrowLeft' && evt.target.matches('input'))
{
evt.target.value = '';
console.clear()
console.log(`element.id = "${ evt.target.id }"`)
}
}
.square {
margin : .2em;
width : 6em;
}
<div id="container"></div>
I am trying to change the backgound color of a div when clicked depending on a property of the object but I am stuck on how to check the property for each object.
The two dimensional array with total 5x5 25 objects:
let tab = [[object{bombe: false}, object{bombe: false}, object{bombe:
true}, object{bombe: false}, object{bombe: true}], [object{bombe:
false}, ...
Function to create an HTML table and set an ID with 2 numbers to each div:
function afficher() {
for (let i = 0; i < 5; ++i) {
for (let j = 0; j < 5; ++j) {
let element = document.createElement("div");
element.innerHTML = " ";
element.id = `${i}${j}`;
document.body.appendChild(element);
}
document.write("<br>");
}
}
Add a function that would add a class to a div depending on the 'bombe' property:
let cellules = document.querySelectorAll("div");
cellules.forEach(c => c.addEventListener("click", jeu));
function jeu() {
if (this.id.bombe) {
this.setAttribute("class", "red");
cellules.forEach(c => c.removeEventListener("click", jeu));
} else {
this.setAttribute("class", "grey");
}
}
I know that this code will display true or false but this is only for one object ... :
let x = tab[0][0].bombe
console.log(x);
Any way I can do this with a forEach ?
If I got your question correctly, you wish to apply certain styles to 2d-array of divs based on colormap stored in a variable.
Without employing jQuery, I'd go lazy way: manipulate innerHTML's rather than DOM object and render all at once (within one function).
You might find an example below:
var matrix = [[{attr:false}, {attr:false}, {attr:true}, {attr:false}, {attr:true}],
[{attr:true}, {attr:false}, {attr:false}, {attr:true}, {attr:true}],
[{attr:false}, {attr:true}, {attr:true}, {attr:false}, {attr:false}],
[{attr:false}, {attr:false}, {attr:true}, {attr:false}, {attr:false}],
[{attr:true}, {attr:true}, {attr:false}, {attr:true}, {attr:false}]]
var renderer = (arg) => {
arg.forEach((row,rownum) => {
document.querySelector('#box').innerHTML += '<div class="row" rownum="'+rownum+'">';
row.forEach((cell,cellnum) => {
let conditionalClass = cell.attr ? 'grey' : 'red';
document.querySelector('[rownum="'+rownum+'"]').innerHTML += '<div class="cell '+conditionalClass+'" cellnum="'+cellnum+'">'
});
document.querySelector('#box').innerHTML += '</div>';
});
};
renderer(matrix);
.row {
height: 30px;
}
.cell {
width: 30px;
height: 100%;
float: left;
}
.red {
background-color: red;
}
.grey {
background-color: grey;
}
<div id="box"></div>
You could use something like :
function afficher(tab) {
tab.forEach( (row, i) => {
row.forEach( (obj, j) => {
let element = document.createElement("div");
element.innerHTML = " ";
element.id = `${i}${j}`;
document.body.appendChild(element);
});
document.write("<br>");
});
}
Note that you'll have to pass tab as an argument when using afficher