Passing javaScript from one page to another in wordpress - javascript

This is javascript code of getting the REST API using strapi.
Im looping through myObject array and printing out products dynamically.
Im getting the element.id from the loop and saving it in a variable with a function called getInfo. The code is currently switching
let laptopsUrl = ''
function getInfo(props){
laptopsUrl = '/'+ props
console.log(laptopsUrl);
renderObjects(laptopsUrl);
}
async function renderObjects(props){
let apiUrl = "http://localhost:1337";
console.log(apiUrl);
console.log('test'+ props);
let urlLocalhost = apiUrl +`/api/Laptops${props}?populate=`;
console.log('Hello' + props)
let stringResponse = await fetch (urlLocalhost);
let myobject = await stringResponse.json();
let output = '';
let index = 0;
let title = '';
let details = '';
let price = '';
let qty = '';
//Kolla om data är en array
if(Array.isArray(myobject.data)){
myobject.data.forEach(element => {
let attr = element.attributes;
console.log(element);
output += `
<div class="grid-item" onclick="getInfo(${element.id})">
<div class="laptop-image">
<img src="${laptopsImages[index].image}"></img>
</div>
<div class="item-info">
<div class="item-title">${attr.Title}</div>
<div>Price: ${attr.Price}</div>
<div>Qty: ${attr.Qty}</div>
</div>
</div>
`;
index++;
});
}else{
let object = myobject.data.attributes;
title += `<div class="title"> Title: ${object.Title}</div>`;
details += `<div> Description: ${object.Description}</div>`;
price += `<div> Price: ${object.Price}</div>`;
qty+= `<div> In stock: ${object.Qty}</div>`;
}
document.getElementById('output').innerHTML = output;
document.getElementById("title").innerHTML = title;
document.getElementById("details").innerHTML = details ;
}
renderObjects(laptopsUrl);
This is HTML to print out products
<body>
<div id ="output">
</div>
<div id ="details">
</div>
<div id ="title">
</div>
<!-- </div> -->
</body>

Related

Messing up the dynamic dropdown. What am I doing wrong?

I am trying to add dropdown list dynamically to a WebApp using google appscript. I wrote a few lines of javascript code in the client side to communicate the server side to fetch the data from google-sheets. After a lot of trying, I'm somewhat successful. However, it looks like, whenever I click on the "Add Product" button, for first 1-2 times the array from which the dropdown is generated is empty. As a result the dropdown remains blank. However after 1 or 2 blank dropdowns the it starts working as it's suppose to.
What am I doing wrong ?
I have 3 files-
form.html
code.gs
js_script.html
Link to the google sheet
Content of form.html-
<body>
<div class="container">
<div class = "row">
<h1>Order Form</h2>
</div> <!-- end of row -->
<div class = "row">
<input id="orderno" type="text" class="validate">
<label for="orderno">Order Number</label>
</div> <!-- end of row -->
<div class = "row">
<input id="clientname" type="text" class="validate">
<label for="clientname">Client Name</label>
</div> <!-- end of row -->
<div class = "row">
<input id="clientaddr" type="text" class="validate">
<label for="clientaddr">Client Address</label>
</div> <!-- end of row -->
<div class = "row">
<input id="clientphone" type="text" class="validate">
<label for="clientphone">Client Phone Number</label>
</div> <!-- end of row -->
<div class = "row">
<input id="ordertype" type="text" class="validate">
<label for="ordertype">Order Type</label>
</div> <!-- end of row -->
<div id="productsection"></div>
<div class = "row">
<button id="addproduct">Add Product</button>
</div> <!-- end of row -->
<div class = "row">
<button id="submitBtn">Submit</button>
</div> <!-- end of row -->
</div> <!-- End of "container" class -->
<?!= include("js_script"); ?>
</body>
Content of code.gs
const ssID = "1YKZYgKctsXU3DKTidVVPUhmPXUkzjjocaiMz1S76JAE";
const ss = SpreadsheetApp.openById(ssID);
function doGet(e){
Logger.log(e);
return HtmlService.createTemplateFromFile("form").evaluate();
}
function include(fileName){
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
function appendDataToSheet(userData){
const ws = ss.getSheetByName("orders");
ws.appendRow([new Date(), userData.orderNumber, userData.clientName, userData.clientAddress, userData.clientPhone, userData.orderType, userData.products].flat());
}
function getOptionArray(){
const ws = ss.getSheetByName("product_list");
const optionList = ws.getRange(2, 1, ws.getRange("A2").getDataRegion().getLastRow() - 1).getValues()
.map(item => item[0]);
return optionList;
}
function logVal(data){
Logger.log(data);
}
Content of js_script.html
<script>
let counter = 0;
let optionList = [];
document.getElementById("submitBtn").addEventListener("click", writeDataToSheet);
document.getElementById("addproduct").addEventListener("click", addInputField);
function addInputField(){
counter++;
// The idea is, everytime when "add product" button is clicked, the following element must be added to the "<div id="productoption></div>" tag.
// <div class="row">
// <select id="productX">
// <option>option-X</option>
// </select>
// </div>
const newDivTag = document.createElement('div');
const newSelectTag = document.createElement('select');
newDivTag.class = "row";
newSelectTag.id = "product" + counter.toString();
google.script.run.withSuccessHandler(updateOptionList).getOptionArray();
google.script.run.logVal(optionList); // This is just to test the optionList array if it's updated or not
for(let i = 0; i < optionList.length; i++){
const newOptionTag = document.createElement('option');
newOptionTag.textContent = optionList[i];
newOptionTag.value = optionList[i];
newSelectTag.appendChild(newOptionTag);
}
newDivTag.appendChild(newSelectTag);
document.getElementById('productsection').appendChild(newDivTag);
}
function writeDataToSheet(){
const userData = {};
userData.orderNumber = document.getElementById("orderno").value;
userData.clientName = document.getElementById("clientname").value;
userData.clientAddress = document.getElementById("clientaddr").value;
userData.clientPhone = document.getElementById("clientphone").value;
userData.orderType = document.getElementById("ordertype").value;
userData.products = [];
for(let i = 0; i < counter; i++) {
let input_id = "product" + (i+1).toString();
userData.products.push(document.getElementById(input_id).value);
}
google.script.run.appendDataToSheet(userData);
}
function updateOptionList(arr){
optionList = arr.map(el => el);
}
</script>
About your current issue of However, it looks like, whenever I click on the "Add Product" button, for first 1-2 times the array form which the dropdown is generated is empty. As a result the dropdown remains blank. However after 1 or 2 blank dropdowns the it starts working as it's suppose to., when I saw your script, I thought that the reason for your issue might be due to that google.script.run is run with the asynchronous process. If my understanding is correct, how about the following modification?
In this case, your js_script.html is modified.
Modified script:
<script>
let counter = 0;
// let optionList = []; // Removed
document.getElementById("submitBtn").addEventListener("click", writeDataToSheet);
document.getElementById("addproduct").addEventListener("click", addInputField);
// Modified
function addInputField(){
counter++;
const newDivTag = document.createElement('div');
const newSelectTag = document.createElement('select');
newDivTag.class = "row";
newSelectTag.id = "product" + counter.toString();
google.script.run.withSuccessHandler(arr => {
const optionList = updateOptionList(arr);
google.script.run.logVal(optionList);
for(let i = 0; i < optionList.length; i++){
const newOptionTag = document.createElement('option');
newOptionTag.textContent = optionList[i];
newOptionTag.value = optionList[i];
newSelectTag.appendChild(newOptionTag);
}
newDivTag.appendChild(newSelectTag);
document.getElementById('productsection').appendChild(newDivTag);
}).getOptionArray();
}
function writeDataToSheet(){
const userData = {};
userData.orderNumber = document.getElementById("orderno").value;
userData.clientName = document.getElementById("clientname").value;
userData.clientAddress = document.getElementById("clientaddr").value;
userData.clientPhone = document.getElementById("clientphone").value;
userData.orderType = document.getElementById("ordertype").value;
userData.products = [];
for(let i = 0; i < counter; i++) {
let input_id = "product" + (i+1).toString();
userData.products.push(document.getElementById(input_id).value);
}
google.script.run.appendDataToSheet(userData);
}
// Modified
function updateOptionList(arr){
return arr.map(el => el); // I cannot understand this mean.
}
</script>
or, in this case, updateOptionList might not be required to be used as follows.
<script>
let counter = 0;
// let optionList = []; // Removed
document.getElementById("submitBtn").addEventListener("click", writeDataToSheet);
document.getElementById("addproduct").addEventListener("click", addInputField);
// Modified
function addInputField(){
counter++;
const newDivTag = document.createElement('div');
const newSelectTag = document.createElement('select');
newDivTag.class = "row";
newSelectTag.id = "product" + counter.toString();
google.script.run.withSuccessHandler(optionList => {
google.script.run.logVal(optionList);
for(let i = 0; i < optionList.length; i++){
const newOptionTag = document.createElement('option');
newOptionTag.textContent = optionList[i];
newOptionTag.value = optionList[i];
newSelectTag.appendChild(newOptionTag);
}
newDivTag.appendChild(newSelectTag);
document.getElementById('productsection').appendChild(newDivTag);
}).getOptionArray();
}
function writeDataToSheet(){
const userData = {};
userData.orderNumber = document.getElementById("orderno").value;
userData.clientName = document.getElementById("clientname").value;
userData.clientAddress = document.getElementById("clientaddr").value;
userData.clientPhone = document.getElementById("clientphone").value;
userData.orderType = document.getElementById("ordertype").value;
userData.products = [];
for(let i = 0; i < counter; i++) {
let input_id = "product" + (i+1).toString();
userData.products.push(document.getElementById(input_id).value);
}
google.script.run.appendDataToSheet(userData);
}
</script>
Note:
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".
Reference:
Class google.script.run (Client-side API)

how to reuse a variable with everything and its value in another page of my project

im working on a e-commerce and im trying to do the page where you fill your info, but i cant use my variable cart, or my total.textContent i just need to show my cart, the total of the cart and my form but i cant use any of my variables or functions
enter code here
const container = document.getElementById("container");
const cartContainer = document.getElementById("cart-items");
let cart = [];
export let stock = [
{id: 1, item: "Playera blanca - Logo rojo", precio: 265, imagen: '<img class="cart-review-img" src="./images/Playera blanca - Logo rojo.png" alt="">'
}];
const upDateCart = () => {
cartContainer.innerHTML = ""
cart.forEach((prod) => {
const div = document.createElement("div")
div.className = ("cart-review-cotainer")
div.innerHTML = `
<div class="cart-image col-md-5">
${prod.imagen}
</div>
<div class="col-md-5 d-flex flex-column justify-content-between">
<div>
<p id="cart-item-name">${prod.item}</p>
<p id="cart-item-price">${prod.precio}</p>
</div>
</div>
<div class="col-md-2 delete-container">
<button onclick="deleteItem(${prod.id})" id="delete-item"><img class="delete-img" src="./images/trash-solid.svg" alt=""></button>
</div>
`
cartContainer.appendChild(div)
localStorage.setItem("newCart", JSON.stringify(cart))
})
total.innerText = cart.reduce((acc, prod) => acc + prod.precio, 0)
}
if(localStorage.getItem("newCart")) {
newCart = JSON.parse(localStorage.getItem("newCart"))
console.log(newCart)
upDateCart()
}
window.deleteItem = deleteItem;
window.cart = cart;
window.test = test;
window.newCart = newCart;
my files in vs code
I couldn't run your snippet, but I guess
if(localStorage.getItem("newCart")) {
newCart = JSON.parse(localStorage.getItem("newCart"))
console.log(newCart)
cart = newCart; // 👈 add this line maybe?
upDateCart()
}

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

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

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)}`);

Categories