How to remove all of the divs? with Vanilla JS - javascript

When I want to change the grid, I want the old one to disappear but right now the old one is being added to the new one. So how to remove all of the old divs? https://codepen.io/diana-larussa/pen/RwGMxqL
if (gridDOMElement.value === 'second') {
const elementsCount = 36
for (let index = 0; index < elementsCount; index++) {
const div = document.createElement("div")
container.appendChild(div)
}
container.style.gridTemplateColumns = "repeat(6, 7vmax)"
container.style.gridTemplateRows = "repeat(6, 7vmax)"
}
if (gridDOMElement.value === "third") {
const elementsCount = 70
for (let index = 0; index < elementsCount; index++) {
const div = document.createElement("div")
container.appendChild(div)
}
container.style.gridTemplateColumns = "repeat(10, 7vmax)"
container.style.gridTemplateRows = "repeat(7, 7vmax)"
}
}
document.querySelector("#grid").addEventListener("change", newGrid)```

I added this inside of the newGrid() function and it helped:
const item = document.querySelector('.container')
while (item.firstChild) {
item.removeChild(item.firstChild)
}

Related

Function which take array and return nested list

const generateList = array => {
const newList = document.createElement("ul");
document.body.appendChild(newList);
for(let i = 0; i < array.length; i += 1) {
if(!Array.isArray(array[i])) {
const newItem = document.createElement("li");
newList.appendChild(newItem);
newItem.innerHTML = array[i];
} else if (Array.isArray(array[i])) {
const get = array[i];
const nestedList = document.createElement("li");
document.querySelector("ul").appendChild(nestedList);
const newUl = document.createElement("ul");
document.querySelector("li").appendChild(newUl);
const nestedItem = document.createElement("ul");
nestedList.appendChild(nestedItem);
for (let j = 0; j < get.length; j += 1) {
const nestedItemX = document.createElement("li");
nestedItem.appendChild(nestedItemX);
nestedItemX.innerHTML = get[j];
}
}
}
}
generateList([[0],1,2,[1.1,1.2,1.3],3,["One","Two","Three"]]);
Hello, I have task, make function which take array(for example[1,2,3[3.1,3.2],4]) and make list in HTML like this ul > li > 1 but if nested array its create new empty list. Must be like this, from start like this ul > li > ul > li
I wrote some code but its make inside li empty and I cannot understand why. Please correct me and explain why its happen?
Structure should be like on picture bellow
I see now, you were indeed creating some unneccesary ULs (only visible when inspecting sourcecode). I cleaned it up:
const generateList = array => {
const newList = document.createElement("ul");
for (let i = 0; i < array.length; i += 1){
const newItem = document.createElement("li");
if (!Array.isArray(array[i])){
newItem.innerHTML = array[i];
}
else{
const nestedArray = array[i];
const nestedList = document.createElement("ul");
for (let j = 0; j < nestedArray.length; j += 1){
const nestedItem = document.createElement("li");
nestedItem.innerHTML = nestedArray[j];
nestedList.appendChild(nestedItem);
}
newItem.appendChild(nestedList);
}
newList.appendChild(newItem);
}
document.body.appendChild(newList);
}
generateList([[0],1,2,[1.1,1.2,1.3],3,["One","Two","Three"]]);

how to get the grid to be of the same size

i have created an input button which will add more squares to the grid but i need the grid to be of the same size regardless of how many squares i add to it while the squares become smaller to account for themselves inside the grid
const grid =
document.querySelector('.grid');
const blackButton =
document.querySelector('.blackbutton');
blackButton.addEventListener('click',
blkButton);
const clear =
document.querySelector('.clearbutton')
clear.addEventListener('click',
clearGrid);
const eraserButton =
document.querySelector('.eraserbutton')
eraserButton.addEventListener('click',
ersButton)
const rainbowButton =document.querySelector('.rainbowbutton')
rainbowButton.addEventListener('click',
rbwButton)
//DOM handling
function getGrid(size) {
const grid =
document.querySelector('.grid');
const boxs =
grid.querySelectorAll(".box");
boxs.forEach((div) => div.remove());
grid.style.gridTemplateColumns =
`repeat( ${size} , 1fr)`;
grid.style.gridTemplateRows = `repeat(
${size} , 1fr)`;
let amount = size * size
for (let i = 0; i < amount; i++) {
const box =
document.createElement('div');
box.classList.add('box');
grid.appendChild(box);
}
}
getGrid(16)
function changeSize(input){
if (input >= 2 && input <= 100) {
getGrid(input);
}
else {
console.log("Only between 2 to 100 Fam!")
}
}

JavaScript Custom Star Rating System

I want to create a star rating system that has 5 stars. You can not select a half star, only a whole one. I want to achieve the following: If the user clicks on the star, the cilcked one and the other before it should be activated, and if the user clicks on a lower star deactivate all the stars after the selected one.
Here is what I got so far: The user can select 4 stars out of five (on the fifth click I have a bug which should be solved).
PS: I am working with SVG images but it would be way too ugly to insert in so the [ ] are the empty stars (the default), and the [X] are the selected (active) stars.
Heres my code:
for (let i = 1; i <= 5; i++) { document.getElementById("w__stars").innerHTML += `<span class="r__icon">[ ]</span>`; }
var icon = document.getElementsByClassName("r__icon");
for (let i = 0; i < icon.length; i++) {
icon[i].addEventListener("click", function (e) { console.log("--");
for (let j = 0; j < i+1; j++) {
console.log("i: " +i); console.log("j: "+(j+1)); console.log("Rest: "+ (j+(5-(i+1))));
icon[j].innerHTML = `[X]`;
icon[i+(5-(i+1))].innerHTML = `[ ]`;
}
});
}
<div class="flex flex-row product-star-con" id="w__stars"></div>
Your method just needs a different approach. For instance that inner loop is unnecessary if you are to place this in there icon[j].innerHTML = '[X]'.. which can be placed just within the outer loop.
Also the unnecessary calculations are making the task seem harder than it actually is. And since this is a loop, the i variable will always have the highest value within the loop, since there is no break statement in there
The method below targets the next elements and previous elements relative to the one being clicked at the moment and applies the appropriate 'innerHTML' to them
// Function to get previous and next siblings of the target element
function getSiblings(element, type){
var arraySib = [];
if ( type == 'prev' ){
while ( element = element.previousSibling ){
arraySib.push(element);
}
} else if ( type == 'next' ) {
while ( element = element.nextSibling ){
arraySib.push(element);
}
}
return arraySib;
}
for (var i = 1; i <= 5; i++) { document.getElementById("w__stars").innerHTML += `<span class="r__icon">[ ]</span>`; }
var icon = document.getElementsByClassName("r__icon");
for (var i = 0; i < icon.length; i++) {
icon[i].addEventListener("click", function (e){
this.innerHTML = `[X]`;
var prev = getSiblings(this, 'prev')
var next = getSiblings(this, 'next')
// populate previous siblings
for(p = 0; p < prev.length; p++){
prev[p].innerHTML = `[X]`
}
// clear next siblings
for(n = 0; n < next.length; n++){
next[n].innerHTML = `[]`
}
});
}
<div class="flex flex-row product-star-con" id="w__stars"></div>
Another approach:
// Setting stars
const stars = [];
for (let i = 0; i <= 4; i++) {
stars.push({
active: false,
index: i
});
}
const renderStars = (parentElement, stars, activeContent, notActiveContent) => {
parentElement.innerHTML = '';
stars.forEach(({ active, index }) => {
parentElement.innerHTML += `
<span class="r__icon">${active ? activeContent : notActiveContent}</span>`;
});
Array.from(parentElement.querySelectorAll('.r__icon')).forEach((item, itemIndex) => {
const star = stars.find(({ index }) => index === itemIndex);
stars[star.index].element = item;
item.addEventListener('click', (e) => {
const itemElement = e.target;
const starIndex = stars.findIndex(({ element }) => element === itemElement);
if (starIndex === -1) {
return;
}
const toActive = stars[starIndex].active !== true;
stars = stars.map(star => {
if (toActive) {
// Set items before index to true, and after to false
if (star.index <= starIndex) {
return {
...star,
active: true
};
}
return {
...star,
active: false
};
} else {
// Set items after index to false, and before to true
if (star.index >= starIndex) {
return {
...star,
active: false
};
}
return {
...star,
active: true
};
}
});
renderStars(parentElement, stars, activeContent, notActiveContent);
});
});
};
const setupStars = (stars, activeContent, notActiveContent) => {
const parentElement = document.getElementById("w__stars");
if (!parentElement) {
return;
}
renderStars(parentElement, stars, activeContent, notActiveContent);
};
setupStars(stars, '[X]', '[ ]');
<div class="flex flex-row product-star-con" id="w__stars"></div>

Add "No results found" message on div search

I'm making an audio player, and I have a list of divs acting as my playlist... I'm using JS to make the list, and I'm using this script to search through them:
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
}
else {
items[i].style.display = "";
}
}
// add noresults message at end if all list divs are hidden
if (!items.innerHTML.toLowerCase().includes(input)) {
_('.noResults').innerHTML = `<p>No results found for "${input}"`
}
}
I have a paragraph element at the end of my list (with nothing in it) and I want to show the message (<p>No results found for "${input}") is there some js I can use to accomplish this? The script above is working for the searching, but not working for the message.
Finished result:
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
let counter = 0;
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
counter++;
}
else {
items[i].style.display = "";
}
}
// keeping the result 22 letters long (for asthetic purposes)
let maxLen = 22;
if (input.length > maxLen) {
input = input.substring(0, maxLen - 3) + "...";
}
if (counter >= items.length) {
_('#noResults').innerHTML = `No results found for "${input}"` //add no results message if all items are hidden...
} else {
_('#noResults').innerHTML = `` //else hide the message by removing text.
}
}
Thanks, #Asif !!
I've made a little modification in your function. I hope this will solve your issue.
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
let counter = 0;
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
}
else {
items[i].style.display = "";
counter++;
}
}
// add noresults message at end if all list divs are hidden
if (counter > 0) {
_('.noResults').innerHTML = `<p>No results found for "${input}"`
}
}

Condition pagination javascript

My problem is When I Select page 2 i want to hide element 0-4 and show 5-8 but when i click 0-4 not hide
I thing because My if condition can some one help me about if condition ? or another way to do ?
and can i limit show data when load first time ?
let data = Array.from(Array(15).keys()).map(item => ({ topic: `Header ${item}`, detail: `Detail ${item}`}))
let tourlek = document.querySelector('#tourlek')
let pagination = document.querySelector('#pagination')
let itemPage = document.getElementsByTagName('item-page')
let item = data.length
let page = 1
let limit = 4
let limitFn = Math.ceil(item / limit)
for (let i = 0; i < item; i++) {
let div = document.createElement('div')
div.textContent = `${data[i].topic} - ${data[i].detail}`
div.classList = 'pd'
tourlek.appendChild(div)
}
for (let i = page; i <= limitFn; i++){
let a = document.createElement('a')
a.textContent = `P:${page}`
// addEventListener onPage function when click
a.addEventListener('click', onPage)
a.setAttribute('data-page', page)
page = page + 1
pagination.appendChild(a).href = 'javascript:void(0)'
}
function onPage (event) {
let itemDom = document.querySelectorAll('.pd')
let currentPage = event.target.getAttribute('data-page')
for (let i = 0; i < itemDom.length; i++) {
if (i >= limit * currentPage ) {
itemDom[i].style.display = 'none'
// console.log(0 < limit * currentPage )
} else {
itemDom[i].style.display = ''
}
}
console.log(event.target.getAttribute('data-page'))
}
a {
margin: 0 10px;
}
<div>
<div id="tourlek"></div>
<div id="pagination"></div>
</div>
To start on page 1 just do
document.querySelector("[data-page='1']").click();
To find the range
const lim = currentPage * limit
for (let i = 0; i < itemDom.length; i++) {
itemDom[i].hidden = i > lim || i < lim -limit
}
let data = Array.from(Array(15).keys()).map(item => ({
topic: `Header ${item}`,
detail: `Detail ${item}`
}))
let tourlek = document.querySelector('#tourlek')
let pagination = document.querySelector('#pagination')
let itemPage = document.getElementsByTagName('item-page')
let currentPage = 1;
let item = data.length
let page = 1
let limit = 4
let limitFn = Math.ceil(item / limit)
let lastPage = 1;
for (let i = 0; i < item; i++) {
let div = document.createElement('div')
div.textContent = `${data[i].topic} - ${data[i].detail}`
div.classList = 'pd'
tourlek.appendChild(div)
}
document.querySelector(".box").addEventListener("click", onPage)
for (let i = page; i <= limitFn; i++) {
let a = document.createElement('a')
a.textContent = `P:${page}`
a.setAttribute('data-page', page)
page = page + 1
pagination.appendChild(a).href = 'javascript:void(0)'
}
document.querySelector("[data-page='1']").click();
function onPage(event) {
const tgt = event.target;
if (tgt.id === "arwL") {
const p = currentPage - 1
if (p===0) return
document.querySelector(`[data-page='${p}']`).click()
return;
}
if (tgt.id === "arwR") {
const p = +currentPage + 1
if (p>=data.length) return
document.querySelector(`[data-page='${p}']`).click()
return;
}
let itemDom = document.querySelectorAll('.pd')
currentPage = event.target.dataset.page;
const lim = currentPage * limit
for (let i = 0; i < itemDom.length; i++) {
itemDom[i].hidden = i > lim || i < lim - limit
}
}
a {
padding: 0 10px;
}
.box {
display: flex;
}
#arwL,
#arwR {
cursor: pointer
}
<div>
<div id="tourlek"></div>
<div class='box'>
<div id="arwL"><</div>
<div id="pagination"></div>
<div id="arwR">></div>
</div>
</div>

Categories