How to put the value of a function inside the template literal? - javascript

Im making a comment system and is required to put the stars inside of template literal with the purpose that the number of stars stay next to the name of the person.
Until now the value is showing me "undefined"
screenshoot screenshot comment system
this is the javascript code
const txtNombre = document.getElementById("text-nombre");
const txtParrafo = document.getElementById("text-area");
const boton = document.getElementById("btnAgregar");
const listado = document.getElementById("contenedor-filas");
const radio = document.getElementsByName("rate");
boton.addEventListener("click", agregarALista);
function agregarALista() {
let nombre = txtNombre.value;
var valor = txtParrafo.value;
const elHtml = document.createElement("div");
elHtml.innerHTML = `
<div class="row" id="fila-segunda">
<div class = "col-6">
${nombre}
</div>
<div class = "col-6">
${estrellitas()}
</div>
</div>
<div class="row" id="fila-tercera">
<div class = "col">
${valor}
</div>
</div>
`;
listado.appendChild(elHtml);
txtNombre.value = "";
txtParrafo.value = "";
}
let estrellitas = function() {
radio.forEach(function(elementos) {
if (elementos.checked) {
estrellas = document.createElement("h3");
estrellas.setAttribute("class", "stars");
let s = "";
for (i = 0; i < elementos.value; i++) {
s += "★";
}
estrellas.textContent = s;
listado.appendChild(estrellas);
}
});
}

Your function estrellitas() is missing a return statement and will therefore return undefined. Otherwise, your syntax for including function return values in string template literals is correct:
let x = (a, b) => a > b;
let a = 10, b = 20;
console.log(`${a} is greater than ${b}? ${x(a, b)}`);

Related

How to delete an item from an array from localstorage onclick

I have the following code. It stores the info on localstorage each time the user clicks on an "add to cart" button:
let addCartItemButtons = document.getElementsByClassName('product-description-add')
for (let i = 0; i < addCartItemButtons.length; i++){
let button = addCartItemButtons[i]
button.addEventListener('click', addProduct)
}
function addProduct(event) {
let buttonClicked = event.target
let getTitle = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-title').innerText
let getImage = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-header img').src
let getColor = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li span').innerText
let getSize = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li select').value
let getPrice = buttonClicked.parentElement.parentElement.querySelector('.product-description-price').innerText
let getSpan = buttonClicked.parentElement.parentElement.querySelector('li span').getAttribute('id')
let oldItems = JSON.parse(localStorage.getItem('newProduct')) || [];
let newItem = {
'title': getTitle,
'image': getImage,
'color': getColor,
'size': getSize,
'price': getPrice,
'spanid': getSpan,
};
oldItems.push(newItem);
localStorage.setItem('newProduct', JSON.stringify(oldItems));
}
Then, i have a code that allows me to display the data the user have locally stored by creating divs and displaying the info:
let cartProducts = JSON.parse(localStorage.getItem("newProduct"))
for(let i = 0; i < cartProducts.length; i++){
let newCartProduct = document.createElement('div')
newCartProduct.classList.add('product')
newCartProduct.classList.add('cart')
const image = cartProducts[i].image
const title = cartProducts[i].title
const spanid = cartProducts[i].spanid
const color = cartProducts[i].color
const size = cartProducts[i].size
const price = cartProducts[i].price
let newCartProductContent = `
<div class="product-header cart"><img src="${image}" alt="" /></div>
<div class="product-content">
<h3 class="product-title" id="product-title">
${title}
</h3>
<div class="product-description">
<ul class="product-description-text cart">
<li>Color: <span id="${spanid}">${color} </span></li>
<li>Size: ${size} </li>
<li>Quantity: <input type="number" class="product-description-quantity" min="1" placeholder="2" value="2"></li>
</ul>
<p class="product-description-price" id="price1">
${price}
</p>
**Remove<i class="fas fa-trash"></i>**
</div>
</div>`
newCartProduct.innerHTML = newCartProductContent
let cartItems = document.getElementsByClassName('products_container_first-row')[0]
cartItems.append(newCartProduct)
}
So what i need to do now is to create a function that allows me to delete the data that it's the same which is on localstorage, each time that the user clicks on a "remove" button (in the above code is the line which has the ** ** at beginning and ending), but i cant figure out how to do this. Any ideas? Thanks!
UPDATE: i've come to this code but i get -1 as index for each element:
let addCartItemButtons = document.getElementsByClassName('product-description-add')
for (let i = 0; i < addCartItemButtons.length; i++){
let button = addCartItemButtons[i]
button.addEventListener('click', function(event){
let buttonClicked = event.target
let getTitle = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-title').innerText
let getImage = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-header img').src
console.log(getImage)
let getColor = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li span').innerText
let getSize = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li select').value
let getPrice = buttonClicked.parentElement.parentElement.querySelector('.product-description-price').innerText
let getSpan = buttonClicked.parentElement.parentElement.querySelector('li span').getAttribute('id')
console.log(getSpan)
let oldItems = JSON.parse(localStorage.getItem('newProduct')) || [];
let newItem = {
'id': i+1,
'title': getTitle,
'image': getImage,
'color': getColor,
'size': getSize,
'price': getPrice,
'spanid': getSpan,
};
oldItems.push(newItem);
localStorage.setItem('newProduct', JSON.stringify(oldItems));
})
}
let cartProducts = JSON.parse(localStorage.getItem("newProduct"));
for(let i = 0; i < cartProducts.length; i++){
let newCartProduct = document.createElement('div')
newCartProduct.classList.add('product')
newCartProduct.classList.add('cart')
console.log(newCartProduct)
const id = cartProducts[i].id
const image = cartProducts[i].image
const title = cartProducts[i].title
const spanid = cartProducts[i].spanid
const color = cartProducts[i].color
const size = cartProducts[i].size
const price = cartProducts[i].price
let newCartProductContent = `
<div class="product-header cart" id="${id}"><img src="${image}" alt="" /></div>
<div class="product-content">
<h3 class="product-title" id="product-title">
${title}
</h3>
<div class="product-description">
<ul class="product-description-text cart">
<li>Color: <span id="${spanid}">${color} </span></li>
<li>Size: ${size} </li>
<li>Quantity: <input type="number" class="product-description-quantity" min="1" placeholder="2" value="2"></li>
</ul>
<p class="product-description-price">
${price}
</p>
Remove<i class="fas fa-trash"></i>
</div>
</div>`
newCartProduct.innerHTML = newCartProductContent
let cartItems = document.getElementsByClassName('products_container_first-row')[0]
cartItems.append(newCartProduct)
}
function lsdel(storage_name, value){
if (localStorage.getItem(storage_name) === null) {
} else {
var ls_data = JSON.parse(localStorage.getItem(storage_name));
var index = ls_data.indexOf(value);
console.log("selected index:"+index);
if(index == -1){
// if not matched selected index
} else {
// is matched, remove...
ls_data.splice(index, 1);
localStorage.setItem(storage_name, JSON.stringify(ls_data));
console.log(ls_data);
}
}
}
value is the ID of an element, but ls_data is an array of objects, not IDs. So ls_data.indexOf(value) will not find the object in the array. And even if value were an object, this wouldn't work because object equality is based on identical objects in memory, not comparing contents.
You need to use findIndex to match the id property of an array element.
function lsdel(storage_name, value) {
if (localStorage.getItem(storage_name) === null) {} else {
var ls_data = JSON.parse(localStorage.getItem(storage_name));
var index = ls_data.findIndex(({id}) => id == value);
console.log("selected index:" + index);
if (index == -1) {
// if not matched selected index
} else {
// is matched, remove...
ls_data.splice(index, 1);
localStorage.setItem(storage_name, JSON.stringify(ls_data));
console.log(ls_data);
}
}
}

Draw in two tables vanilla JS

I am working with program that will randomly choose who is making a Christmas gift to whom.
I've created an empty array. When you add a "player" it's pushing the name into two different arrays. Players[] and Players2[].
When you start a draw. The program writes the names of the Players[] on the left hand side and on the right side it writes the drawn names from Players2[].
Every Player from Players2[], after being drawn, is being deleted from the array so in the end we have an empty Players2[] array and full Players[] array.
The problem is: I can't make a working if statement that is checking if the person will not draw himself...
let Players = [];
let Players2 = [];
const addBTN = document.getElementById('addBTN');
const onlyLetters = /^[a-zżźćóęśńłA-ZŻŹĆÓŁĘŚŃŁ ]+$/;
const refreshBTN = document.getElementById('refreshBTN');
const warningBTNyes = document.getElementById('warning-button-yes');
const warningBTNno = document.getElementById('warning-button-no');
const playersList = document.getElementById('playersList');
const playersList2 = document.getElementById('playersList2');
const startBTN = document.getElementById('startBTN');
const drawLotsBTN = document.getElementById('drawLotsBTN');
addBTN.addEventListener('click', function() {
const input = document.getElementById('addPLAYER');
const person = document.getElementById('addPLAYER').value;
if (input.value == "") {
console.log('error_empty_input');
document.getElementById('errorMSG').style.color = "red";
document.getElementById('errorMSG').innerHTML = "Wpisz imię osoby!";
} else if (input.value.match(onlyLetters)) {
console.log('good');
Players.push(person);
Players2.push(person);
playersList.innerHTML = playersList.innerHTML + "<br>" + person;
document.getElementById('addPLAYER').value = "";
document.getElementById('errorMSG').style.color = "green";
document.getElementById('errorMSG').innerHTML = "Powodzenie! Dodaj kolejną osobę.";
} else {
console.log('error_input');
document.getElementById('errorMSG').style.color = "red";
document.getElementById('errorMSG').innerHTML = "Coś jest nie tak z imieniem. Pamiętaj aby wprowadzać same litery!";
}
});
refreshBTN.addEventListener('click', function() {
document.getElementById('warning').style.display = "block";
});
warningBTNyes.addEventListener('click', function() {
location.reload(true);
document.getElementById('addPLAYER').value = "";
});
warningBTNno.addEventListener('click', function() {
document.getElementById('warning').style.display = "none";
});
startBTN.addEventListener('click', function() {
drawLotsBTN.disabled = false;
const input = document.getElementById('addPLAYER');
const person = document.getElementById('addPLAYER').value;
if (input.value == "") {
} else if (input.value.match(onlyLetters)) {
console.log('good');
Players.push(person);
Players2.push(person);
playersList.innerHTML = playersList.innerHTML + "<br>" + person;
document.getElementById('addPLAYER').value = "";
document.getElementById('errorMSG').style.color = "green";
document.getElementById('errorMSG').innerHTML = "Powodzenie! Zaczynasz losowanie!";
} else {
console.log('error_input');
document.getElementById('errorMSG').style.color = "red";
document.getElementById('errorMSG').innerHTML = "Coś jest nie tak z imieniem. Pamiętaj aby wprowadzać same litery!";
}
document.getElementById('addPLAYER').disabled = true;
});
drawLotsBTN.addEventListener('click', function() {
for (let i = 0; i = Players2.length; i++) {
if (Players2.length > 0) {
randomPerson = Math.floor(Math.random() * Players2.length);
if (randomPerson != Players.indexOf(i)) {
console.log(Players2[randomPerson]);
playersList2.innerHTML = playersList2.innerHTML + "<br>" + Players2[randomPerson];
Players2.splice(randomPerson, 1);
}
} else {
console.log('error_empty_array');
}
}
});
<div id="warning" class="warning">
<div class="warning-flex">
<h1>Wszelkie wpisane imiona zostaną usunięte</h1>
<div class="warning-buttons">
<button id="warning-button-yes" class="warning-button-yes">Tak</button>
<button id="warning-button-no" class="warning-button no">Nie</button>
</div>
</div>
</div>
<div class="lotteryContainer">
<div class="left">
<p>dodaj osobę</p>
<div class="addPerson">
<input required id="addPLAYER" type="text">
<button id="addBTN">+</button>
<p id="errorMSG"></p>
<div class="refresh">
<button id="refreshBTN">Od nowa</button>
<button id="startBTN">Start</button>
</div>
</div>
</div>
<div class="right">
<p>Uczestnicy</p>
<div class="tables">
<div class="tableLeft">
<p id=playersList></p>
</div>
<div class="tableRight">
<p id="playersList2"></p>
</div>
</div>
<button id="drawLotsBTN">Losuj</button>
</div>
</div>
<script src="app.js"></script>
Now if I understand what your program aims to do, there is a simple algorithm for it.
How I understand your goal:
You have a list of persons who are going to give presents to each other. (like in secret Santa). It is random who will give to who, but each person gives and receives one gift.
How to implement it (i'd normaly use maps, but I am guessing you are more comfortable with arrays):
players = ["Adam", "Bret", "Clay", "Donald"];
players.sort(function(a, b){return 0.5 - Math.random()}); // shuffles array
gives_to = [...players]; // copy values of array
gives_to.push(gives_to.shift()); // let the first element be the last
Here the first player (players[0]) will give to gives_to[0] and the second to gives_to[1] etc.
I've created this JS script trying to use Trygve Ruud algorithm but it doesn't work like desired.
drawLotsBTN.addEventListener('click', function(){
if(Players.length > 0) {
console.log(Players)
Players.sort(function(a, b){
return 0.5 - Math.random();
});
for(let i = 0; i < Players.length; i++){
playersList2.innerHTML = playersList2.innerHTML + "<br>" + Players[i];
}
}
else{
console.log('error_empty_array');
}
});

All buttons only affect one input instead of respective input

I am making a little project for my self. So basically its main function is to create a base counter for each game.
For example: If there are two players it should create three bases. (This is for the card game "smash up" if that helps you understand better.) But when the Buttons populate they all only effect the last input. I can not figure out how to make them effect their respective inputs.
The problem I am having is that every button I click only effects the last input.
<html>
<title> Base Maker </title>
<body>
<div>
<hl> Score Keeper </h1>
<hr>
<input type = "text" placeholder = "How many players?">
<button id = "enter" onclick = "baseMaker()">
Enter
</button>
</div>
<p></p>
</body>
</html>
var parent = document.querySelector("p");
var input = document.querySelector("input");
var enter = document.getElementById("enter");
function baseMaker()
{
for(var i = 0; i <= input.value; i++)
{
//base
var base = document.createElement("p");
base.textContent = "Base " + (i + 1) + ":";
//score
var score = document.createElement( "input");
score.setAttribute("id", "score" + i);
score.value = 20;
//upbutton
var upButton = document.createElement( "button");
upButton.textContent = "+";
upButton.setAttribute("id", "upButton" + i)
upButton.addEventListener('click', function() {
score.value++; });
//downbutton
var downButton = document.createElement( "button");
downButton.textContent = "-";
downButton.setAttribute("id", "downButton" + i)
downButton.addEventListener('click', function() {
score.value--; });
//populate data
parent.appendChild(base);
parent.appendChild(score);
parent.appendChild(upButton);
parent.appendChild(downButton);
}
input.value = "";
}
This is a common thing to run into especially when not using a framework in javascript.
I am not sure why this happens but when a function is defined directly in a loop, the closure for these created functions becomes whatever it is after the last iteration. I believe it is because the closure for each callback function is only "sealed up" (for lack of a better word) at the end of the loop-containing-function's execution which is after the last iteration. It's really beyond me, though.
There are some easy ways to avoid this behavior:
use bind to ensure a callback gets called with the correct input (used in solution at bottom)
create a function which creates a handler function for you and use that in the loop body
function createIncrementHandler(input, howMuch){
return () => input.valueAsNumber += howMuch;
}
/// then in your loop body:
downButton.addEventListener('click', createIncrementHandler(score, 1));
get the correct input by using the event parameter in the handler
downButton.addEventListener('click', (event) => event.target.valueAsNumber += 1);
make the entire body of the loop into a function, for example:
function createInputs(i) {
//base
var base = document.createElement("p");
base.textContent = "Base " + (i + 1) + ":";
//score
var score = document.createElement("input");
score.type = "number";
score.setAttribute("id", "score" + i);
score.value = 20;
//upbutton
var upButton = document.createElement( "button");
upButton.textContent = "+";
upButton.setAttribute("id", "upButton" + i)
upButton.addEventListener('click', function() {
score.value++; });
//downbutton
var downButton = document.createElement( "button");
downButton.textContent = "-";
downButton.setAttribute("id", "downButton" + i)
downButton.addEventListener('click', function() {
score.value--; });
//populate data
parent.appendChild(base);
parent.appendChild(score);
parent.appendChild(upButton);
parent.appendChild(downButton);
}
Here is a full example of one of the possible fixes.
<html>
<title> Base Maker </title>
<body>
<div>
<hl> Score Keeper </h1>
<hr>
<input type="text" placeholder="How many players?">
<button id="enter" onclick="baseMaker()">
Enter
</button>
</div>
<p></p>
<script>
var parent = document.querySelector("p");
var input = document.querySelector("input");
var enter = document.getElementById("enter");
function incrementInput(input, byHowMuch) {
input.valueAsNumber = input.valueAsNumber + byHowMuch;
}
function baseMaker() {
for (var i = 0; i <= input.value; i++) {
//base
var base = document.createElement("p");
base.textContent = "Base " + (i + 1) + ":";
//score
var score = document.createElement("input");
score.type = "number";
score.setAttribute("id", "score" + i);
score.value = 20;
//upbutton
var upButton = document.createElement("button");
upButton.textContent = "+";
upButton.setAttribute("id", "upButton" + i)
upButton.addEventListener('click', incrementInput.bind(null, score, 1));
//downbutton
var downButton = document.createElement("button");
downButton.textContent = "-";
downButton.setAttribute("id", "downButton" + i)
downButton.addEventListener('click', incrementInput.bind(null, score, -1));
//populate data
parent.appendChild(base);
parent.appendChild(score);
parent.appendChild(upButton);
parent.appendChild(downButton);
}
input.value = "";
}
</script>
</body>
</html>
I will do that this way :
const
AllBases = document.querySelector('#bases')
, bt_Start = document.querySelector('#game-go')
, bt_newGame = document.querySelector('#new-game')
, playerCount = document.querySelector("#play-start > input")
;
playerCount.value = ''
playerCount.focus()
playerCount.oninput = () =>
{
playerCount.value.trim()
bt_Start.disabled = (playerCount.value === '' || isNaN(playerCount.value))
playerCount.value = (bt_Start.disabled) ? ''
: (playerCount.valueAsNumber > playerCount.max) ? playerCount.max
: (playerCount.valueAsNumber < playerCount.min) ? playerCount.min
: playerCount.value
}
bt_newGame.onclick = () =>
{
playerCount.value = ''
playerCount.disabled = false
bt_Start.disabled = true
bt_newGame.disabled = true
AllBases.innerHTML = ''
playerCount.focus()
}
bt_Start.onclick = () =>
{
playerCount.disabled = true
bt_Start.disabled = true
bt_newGame.disabled = false
for(let i = 0; i <= playerCount.valueAsNumber; i++)
{
let base = document.createElement('p')
base.countValue = 20 // create a counter property on <p>
base.innerHTML = `Base ${i+1} : <span>${base.countValue}</span> <button>+</button> <button>−</button>\n`
AllBases.appendChild(base)
}
}
AllBases.onclick = ({target}) =>
{
if (!target.matches('button')) return // verify clicked element
let countElm = target.closest('p')
if (target.textContent==='+') countElm.countValue++
else countElm.countValue--
countElm.querySelector('span').textContent = countElm.countValue
}
#bases p span {
display : inline-block;
width : 6em;
border-bottom : 2px solid aqua;
padding-right : .2em;
text-align : right;
margin : 0 .3em;
}
#bases p button {
width : 2em;
margin : 0 .1em;
cursor : pointer;
}
<hr>
<hl> Score Keeper </h1>
<hr>
<div id="play-start" >
<input type="number" placeholder="How many players?" min="2" max="4">
<button id="game-go" disabled> Enter </button>
<button id="new-game" disabled> new </button>
</div>
<hr>
<div id="bases"></div>
If it helps, I can add more explanations

The items in the DOM are added multiple times

I got a problem,each time I add the element,it multiplicates itself(for example if there is 1 element in the cart,on the next click it will add 2 more,and if there are 3 elements,it will add 3 more,if 6,it will add 4 more),that's a huge problem,please help!
My js code:
let pList = document.getElementById("productList");
const addDrip = () => {
let Drip, localObj, tObj;
Drip = {
name: "Traditional Drip",
type: "normal",
price: "2.00",
imgSrc: "images/c5.png"
};
localObj = localStorage.getItem("Drip");
if(!localObj) tObj = [];
else tObj = JSON.parse(localObj);
tObj.push(Drip)
localStorage.setItem("Drip", JSON.stringify(tObj));
for(let i = 0;i < tObj.length;i++){
let htmlDrip = `
<div class="productDiv">
<p>${tObj[i].name}</p>
<p>${tObj[i].type}</p>
<p>${tObj[i].price}$</p>
<img src="${tObj[i].imgSrc}">
</div>
`
document.getElementById("productList").innerHTML += htmlDrip;
}
}
My html part:
<div class="cList">
<img src="images/c5.png"class = "tDrip">
<h1 class="Type">Traditional Drip</h1>
<button id="tAdd"onclick="addDrip()">Add Traditional Drip</button>
</div>
<div id = productList></div>
This is because your array already has the drip update from the localstorage
Simply replace your JS code with this and it will work desired way you want.
let pList = document.getElementById("productList");
const addDrip = () => {
let Drip, localObj, tObj;
Drip = {
name: "Traditional Drip",
type: "normal",
price: "2.00",
imgSrc: "images/c5.png"
};
localObj = localStorage.getItem("Drip");
console.log(localObj,"Local object")
if(!localObj) {
tObj = [];
tObj.push(Drip)
}else {
tObj = JSON.parse(localObj);
console.log(tObj,"T object")
}
localStorage.setItem("Drip", JSON.stringify(tObj));
for(let i = 0;i < tObj.length;i++){
let htmlDrip = `
<div class="productDiv">
<p>${tObj[i].name}</p>
<p>${tObj[i].type}</p>
<p>${tObj[i].price}$</p>
<img src="${tObj[i].imgSrc}">
</div>
`
document.getElementById("productList").innerHTML += htmlDrip;
}
}
you just have to push when your array is empty. Give it a try it will work.
NOTE : you can check the demo too. Just clear the localstorage if you refresh.https://www.w3schools.com/code/tryit.asp?filename=GS7FA0970MF3
You don't actually need to loop thru the array while adding the new item.
You can first get the items from localStorage
HTML:
<div class="cList">
<img src="images/c5.png" class="tDrip">
<h1 class="Type">Traditional Drip</h1>
<button id="tAdd" onclick="addDrip()">Add Traditional Drip</button>
</div>
<div id="productList"></div>
Script:
const pList = document.getElementById("productList");
let localObj = JSON.parse(localStorage.getItem("Drip"));
const parseItems = () => {
if (!localObj) localObj = [];
for (let i = 0; i < localObj.length; i++) {
let htmlDrip = `
<div class="productDiv">
<p>${localObj[i].name}</p>
<p>${localObj[i].type}</p>
<p>${localObj[i].price}$</p>
<img src="${localObj[i].imgSrc}">
</div>
`;
pList.innerHTML += htmlDrip;
}
}
parseItems();
const addDrip = () => {
let Drip;
Drip = {
name: "Traditional Drip",
type: "normal",
price: "2.00",
imgSrc: "images/c5.png"
};
if (!localObj) localObj = [];
localObj.push(Drip);
localStorage.setItem("Drip", JSON.stringify(localObj));
let htmlDrip = `
<div class="productDiv">
<p>${Drip.name}</p>
<p>${Drip.type}</p>
<p>${Drip.price}$</p>
<img src="${Drip.imgSrc}">
</div>
`;
pList.innerHTML += htmlDrip;
}

Repeated objects with input values

I have a javascript repeater that creates forms,
but the problem is that when I bring the values ​​they are all entered in a single object instead of separate objects, which inside array locations should create a similar structure.
"locations":[
{
"coordinates":[
-80.128473,
25.781842
],
"description":"Lummus Park Beach",
"day":1
},
{
"coordinates":[
-80.647885,
24.909047
],
"description":"Islamorada",
"day":2
},
]
My code takes information from inputs but puts it in the same object instead of separate objects.
//This is the code which take input value and inser in boject structure
const createTour_form = document.querySelector('.form-create__tour');
if (createTour_form) {
createTour_form.addEventListener('submit', (cr) => {
cr.preventDefault();
//Ceeate an empty array
let loc_coordinates = [];
let loc_description = [];
let loc_day = [];
let get_locations = [];
//Get Coordinates
document.querySelectorAll(".location_field_card").forEach(f => {
let obj = [];
f.querySelectorAll(".location_new_tour").forEach(ele => obj[ele.value] = ele.value || "");
loc_coordinates.push(Object.keys(obj));
});
//Get Descriptions
document.querySelectorAll(".location_field_card").forEach(f => {
let obj1 = {};
f.querySelectorAll(".description_location").forEach(ele => obj1[ele.name] = ele.value || "");
loc_description.push(obj1)
});
//Get Day
document.querySelectorAll(".location_field_card").forEach(f => {
let obj2 = {};
f.querySelectorAll(".location_day").forEach(ele => obj2[ele.name] = ele.value || "");
loc_day.push(obj2)
});
//Reverse Coordinates
const getGeo = [...loc_coordinates].toString().split(',').reverse().join(' ').replace(' ', ' ,');
get_locations.push(getGeo)
const getLocation = Object.values(...loc_description);
const getValLocation = getLocation.toString();
const getDay = Object.values(...loc_day);
const getValDay =parseInt(getDay.toString());
let getTotaLocation = new Object({
"coordinates":[...get_locations],
"description":getValLocation,
"day":getValDay
});
console.log(getTotaLocation);
})
}
<form class="form form-create__tour">
<h1 class="title--create--tourpage">Locations</h1>
<div class="form__group all_tours_options">
<div id="add_location_field">
<div class="location_field_card">
<p class="subfield_natours_create_tour">Location</p>
<input class="form__input location_new_tour" type="text" value="24.5647846,-81.8068843">
<p class="subfield_natours_create_tour">Location Description</p>
<input class="form__input description_location" type="text" value="Lummus Park Beach">
<p class="subfield_natours_create_tour">Day</p>
<input class="form__input location_day" type="number" value="1" >
</div>
</div>
<button class="btn btn--small--add btn--green" id="add_location_fields">Add Location Field</button>
</div>
<div class="form__group right"><button class="btn btn--small btn--green" id="createTour">Create Tour</button></div>
</form>
<!--This Javascript code generate new fields when Add Locaton field is clicked-->
<script>
const addLocation = document.getElementById('add_location_fields');
if(addLocation){
let count_createdCards = 0;
let count_Deletebutton = 0;
let incrementFunction = 0;
addLocation.addEventListener('click',(st)=>{
st.preventDefault();
let createAddField = document.getElementById('add_location_field');
// Crd
count_createdCards++;
count_Deletebutton ++;
incrementFunction ++;
let card = document.createElement('div');
card.setAttribute('class','location_field_card');
card.setAttribute('id','delete_card_'+ count_createdCards)
//First Card Title
let cartTitle1 = document.createElement('p');
cartTitle1.setAttribute('class','subfield_natours_create_tour');
cartTitle1.textContent = 'Location';
let inputLocation = document.createElement('input');
inputLocation.classList.add('form__input');
inputLocation.classList.add('location_new_tour');
inputLocation.setAttribute('type','text');
inputLocation.setAttribute('value','24.5647846,-81.8068843');
//Second Card Title
let cartTitle2 = document.createElement('p');
cartTitle2.setAttribute('class','subfield_natours_create_tour');
cartTitle2.textContent = 'Location Description';
let inputDescription_location = document.createElement('input');
inputDescription_location.classList.add('form__input');
inputDescription_location.classList.add('description_location');
inputDescription_location.setAttribute('type','text');
inputDescription_location.setAttribute('value','Lummus Park Beach');
//Third Card Title
let cartTitle3 = document.createElement('p');
cartTitle3.setAttribute('class','subfield_natours_create_tour');
cartTitle3.textContent = 'Day';
let inputDescription_day = document.createElement('input');
inputDescription_day.classList.add('form__input');
inputDescription_day.classList.add('location_day');
inputDescription_day.setAttribute('type','number');
inputDescription_day.setAttribute('value','1');
let removeButton = document.createElement('a');
removeButton.classList.add('btn');
removeButton.classList.add('btn--small--add');
removeButton.classList.add('btn--red');
removeButton.setAttribute('onclick','removeAction_'+count_Deletebutton+'()');
let removeScript = document.createElement('script');
removeScript.innerHTML = "function removeAction_".concat(count_Deletebutton, "() {\n\n var delCard_")
.concat(incrementFunction, " = document.getElementById(\"delete_card_")
.concat(count_createdCards, "\");\ndelCard_")
.concat(incrementFunction, ".remove();}");
removeButton.textContent = 'Remove Location Field';
card.appendChild(cartTitle1);
card.appendChild(inputLocation);
card.appendChild(cartTitle2);
card.appendChild(inputDescription_location);
card.appendChild(cartTitle3);
card.appendChild(inputDescription_day);
card.appendChild(removeButton);
card.appendChild(removeScript);
createAddField.appendChild(card);
});
}
</script>
I solved the problem by adding in the folds that repeat the dynamic id:
//Increment Coordinates
let incrementCoordiantes = 0;
//Increment Description
let incrementDescription = 0;
//Increment Day
let incrementDay = 0;
addLocation.addEventListener('click',(st)=>{
let createAddField = document.getElementById('add_location_field');
incrementCoordiantes ++;
incrementDescription ++;
incrementDay ++;
let card = document.createElement('div');
......
inputLocation.setAttribute('id','getCoordinates_'+ incrementCoordiantes);
inputDescription_location.setAttribute('id','getDescription_' + incrementDescription);
inputDescription_day.setAttribute('id','getDay_' + incrementDay );
I use querySelectorAll to get the number of colums from repeater and after that I use for to incremet id to match the id from html file, all the value it's push after that in an array, and it's work.
const push_location_data = [];
const getAll_locations = document.querySelectorAll(".location_field_card");
for (let i=1; i< getAll_locations.length; i++) {
let cord_lat_lng = 'getCoordinates_' + i;
let cord_description = 'getDescription_' + i;
let cord_day = 'getDay_' + i;
let dinamic_obj = {
coordinates:[[document.getElementById(cord_lat_lng).value].toString().split(',').reverse().join(' ').replace(' ', ' ,')],
description:document.getElementById(cord_description).value,
day:document.getElementById(cord_day).value
}
push_location_data.push(dinamic_obj);
};
location arrray

Categories