const Sheet = [
{
"Code": "A-0-1",
"UPC": "Photos/4009803054728.jpg",
"Title": "U.S.S. Constitution",
"Price": "$34",
"InStock": "7"
},
{
"Code": "A-0-2",
"UPC": "Photos/4009803073996.jpg",
"Title": "Revell 07399 VW Samba Bus Model Kit",
"Price": "$38",
"InStock": "8"
},
]
const productsEl = document.querySelector(".Sheet");
function getProducts() {
Sheet.forEach((product) => {
productsEl.innerHTML += `<div class="productContainer">
<div class="img">
<img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc">
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price"><span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="addToCart" onclick="addToCart();">
<button id="addToCart" > Add to Cart</button>
</div>
</div>`;
})
}
getProducts();
function addToCart() {
console.log(document.getElementById("itemName").innerText)
}
<div class="Sheet">
</div>
All right, the add to cart button only logs the first data in my object. No matter which one I press it's always the first one. I tried .val and no luck. How can I log the item that was pressed instead?
You can pass the name of product as an argument to the addToCart() function
like below
const Sheet = [
{
"Code": "A-0-1",
"UPC": "Photos/4009803054728.jpg",
"Title": "U.S.S. Constitution",
"Price": "$34",
"InStock": "7"
},
{
"Code": "A-0-2",
"UPC": "Photos/4009803073996.jpg",
"Title": "Revell 07399 VW Samba Bus Model Kit",
"Price": "$38",
"InStock": "8"
},
]
const productsEl = document.querySelector(".Sheet");
function getProducts() {
Sheet.forEach((product) => {
productsEl.innerHTML += `<div class="productContainer">
<div class="img">
<img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc">
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price"><span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="addToCart" onclick="addToCart(product.Title);">
<button id="addToCart" > Add to Cart</button>
</div>
</div>`;
})
}
getProducts();
function addToCart(productTitle) {
console.log(productTitle)
}
You have to pass the product's index as a parameter to the AddToCart() function.
Advantages of this implementation
Allows you to access other properties of the product's object like Price, InStock, etc.
If you change the property name of "Title" to something else, you only need to update the AddToCart function code, not the getProducts()'s AddToCart call-to-action.
Advice: You should try to avoid fetching items via html id or innerText (this was a norm a decade or more ago, not anymore). Try using more of data attributes
const Sheet = [
{
"Code": "A-0-1",
"UPC": "Photos/4009803054728.jpg",
"Title": "U.S.S. Constitution",
"Price": "$34",
"InStock": "7"
},
{
"Code": "A-0-2",
"UPC": "Photos/4009803073996.jpg",
"Title": "Revell 07399 VW Samba Bus Model Kit",
"Price": "$38",
"InStock": "8"
},
]
const productsEl = document.querySelector(".Sheet");
function getProducts() {
Sheet.forEach((product, productIndex) => {
productsEl.innerHTML += `<div class="productContainer">
<div class="img">
<img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc">
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price"><span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="addToCart" onclick="addToCart(`+productIndex+`);">
<button id="addToCart" > Add to Cart</button>
</div>
</div>`;
})
}
getProducts();
function addToCart(productIndex) {
var product = Sheet[productIndex];
console.log(product.Title);
}
<div class="Sheet">
</div>
Explanation
The parameters of a forEach function allows for the index of the current iteration. read more here
Try like this
const Sheet = [
{
"Code": "A-0-1",
"UPC": "Photos/4009803054728.jpg",
"Title": "U.S.S. Constitution",
"Price": "$34",
"InStock": "7"
},
{
"Code": "A-0-2",
"UPC": "Photos/4009803073996.jpg",
"Title": "Revell 07399 VW Samba Bus Model Kit",
"Price": "$38",
"InStock": "8"
},
]
const productsEl = document.querySelector(".Sheet");
function getProducts() {
Sheet.forEach((product) => {
productsEl.innerHTML += `<div class="productContainer">
<div class="img">
<img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc" >
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price"><span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="addToCart" onclick="">
<button class="addToCartBtn" id="${product.Code}"> Add to Cart</button>
</div>
</div>`;
})
}
getProducts();
var elements = document.querySelectorAll(".addToCartBtn");
elements.forEach(element => {
element.addEventListener("click", function (e) {
console.log(e.target.id);
//other function
});
});
<div class="Sheet">
</div>
Use this instead...
const productsEl = document.querySelector(".Sheet");
const Sheet = [
{
"Code": "A-0-1",
"UPC": "Photos/4009803054728.jpg",
"Title": "U.S.S. Constitution",
"Price": "$34",
"InStock": "7"
},
{
"Code": "A-0-2",
"UPC": "Photos/4009803073996.jpg",
"Title": "Revell 07399 VW Samba Bus Model Kit",
"Price": "$38",
"InStock": "8"
},
];
(function getProducts() {
Sheet.forEach(product => {
productsEl.innerHTML += `<!-- ${product.Title} -->
<div class="productContainer">
<div class="img">
<img src="${product.UPC}" alt="${product.Title}" height="170px" width="170px">
</div>
<div class="itemDesc">
<h2 class="name">${product.Title}</h2>
<h4 class="price">${product.Price}</h4>
<div class="desc">
<p>${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="addToCart">
<!-- This will ensure you're only getting the current product (via the button) -->
<button onclick="addToCart(this)"> Add to Cart</button>
</div>
</div>`;
})
})();
function addToCart(button) {
const parent = button.closest('.productContainer');
// This will travel up the DOM chain from the button to the nearest element with `class="... productContainer ..."`
const element = parent.querySelector('.name');
// This will travel back down the DOMchain to the element with `class="... name ..."`
console.log(element.innerText);
}
<div class="Sheet"></div>
Related
I have an HTML page and I want to show the chat content between two person, the chat box is like this:
let data = {
"lyrics": [{
"line": "line 1 start",
"position": "r",
"time": 4.5
},
{
"line": "answer 1",
"position": "l",
"time": 9.03
},
{
"line": "line 2 start",
"position": "r",
"time": 14.01
}
]
}
<!-- right chat -->
<div class="chat__conversation-board__message-container reversed">
<div class="chat__conversation-board__message__person">
<div class="chat__conversation-board__message__person__avatar">
<img src="./customer.jpg" alt="Dennis Mikle" />
</div>
<span class="chat__conversation-board__message__person__nickname">Dennis Mikle</span>
</div>
<div class="chat__conversation-board__message__context">
<div class="chat__conversation-board__message__bubble">
<span>some text</span>
</div>
</div>
</div>
<!-- left chat -->
<div class="chat__conversation-board__message-container">
<div class="chat__conversation-board__message__person">
<div class="chat__conversation-board__message__person__avatar">
<img src="./agent.jpg" alt="Monika Figi" />
</div>
<span class="chat__conversation-board__message__person__nickname">Monika Figi</span>
</div>
<div class="chat__conversation-board__message__context">
<div class="chat__conversation-board__message__bubble">
<span>some text</span>
</div>
</div>
</div>
I get the data.json from the server and display it on index.html and I want to create the element with position type (left=l or right=r) inside my body.
Here is my example code for your reference:
let data={
"lyrics": [
{
"line": "line 1 start",
"position": "r",
"time": 4.5
},
{
"line": "answer 1",
"position": "l",
"time": 9.03
},
{
"line": "line 2 start",
"position": "r",
"time": 14.01
}
]
}
function go(){
let container;
data.lyrics.forEach(lyric=>{
if (lyric.position === 'r') {
container=document.querySelector(".right .chat__conversation-board__message__bubble");
} else {
container=document.querySelector(".left .chat__conversation-board__message__bubble");
}
container.innerHTML+="<div>"+lyric.line+"</div>";
})
}
<div class="chat__conversation-board__message-container reversed right">
<div class="chat__conversation-board__message__person">
<div class="chat__conversation-board__message__person__avatar">
<img src="./customer.jpg" alt="Dennis Mikle" />
</div>
<span class="chat__conversation-board__message__person__nickname">Dennis Mikle</span>
</div>
<div class="chat__conversation-board__message__context">
<div class="chat__conversation-board__message__bubble">
<span>some text</span>
</div>
</div>
</div>
<!-- left chat -->
<div class="chat__conversation-board__message-container left">
<div class="chat__conversation-board__message__person">
<div class="chat__conversation-board__message__person__avatar">
<img src="./agent.jpg" alt="Monika Figi" />
</div>
<span class="chat__conversation-board__message__person__nickname">Monika Figi</span>
</div>
<div class="chat__conversation-board__message__context">
<div class="chat__conversation-board__message__bubble">
<span>some text</span>
</div>
</div>
</div>
<button onclick="go()">
Go
</button>
I have added "right" and "left" to the class name of the containers.
So, I can base on the "position" attribute to select the appropriate containers to store the new content.
const Sheet = [
{
"Code": "A-0-1",
"UPC": "Photos/4009803054728.jpg",
"Title": "U.S.S. Constitution",
"Price": "$34",
"InStock": "7"
},
]
const productsEl = document.querySelector(".Sheet");
function getProducts() {
Sheet.forEach((product) => {
productsEl.innerHTML += `<div class="productContainer">
<div class="img">
<img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc">
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price"><span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="addToCart" onclick="addToCart(this);">
<button id="addToCart" > Add to Cart</button>
</div>
</div>`;
})
}
getProducts();
let numUnit = document.getElementById("#Unit")
let itemTitle = document.getElementById("item")
let itemPrice = document.getElementById("$Price")
function addToCart(button) {
const parent = button.closest('.productContainer'),
Title = parent.querySelector('#itemName')
Price = parent.querySelector('#price')
Code = parent.querySelector('#desc')
itemTitle.textContent = Title.innerText + ' ' + Code.innerText
itemPrice.textContent = Price.innerText
//numUnit.textContent = '1'
}
<div class="Sheet">
</div>
<div class="cartContainer">
<div class="cart">
<h3>Cart: <span id="allNum"> 0</span></h3>
</div>
<div class="itemUl">
<ul>
<li id="Units">Units:<span id="#Unit"></span></li>
<li id="Items">Item:<span id="item"></span></li>
<li id="Price">Price:<span id="$Price"></span></li>
</ul>
</div>
</div>
Currently, when I press addToCart the title and price go to my cart but then when I press it again it replaces it. How can I add it below instead of replacing it? I know there is a way to create elements but I was wondering if there is another way since my elements are already created.
This question already has answers here:
How to filter object array based on attributes?
(21 answers)
Closed 8 months ago.
const Sheet = [
{
"Code": "A-0-1",
"UPC": "4009803054728",
"Expr1": "Photos/4009803054728.JPG",
"Title": "U.S.S. Constitution",
"Price": " 31 ",
"InStock": " 7 ",
"Category": "Toys"
},
{
"Code": "C-1-1",
"UPC": "662248910376",
"Expr1": "Photos/662248910376.JPG",
"Title": "PS3 TOMB RAIDER TRILOGY",
"Price": " 29 ",
"InStock": " 4 ",
"Category": "Video Games"
},
{
"Code": "C-1-12",
"UPC": "719192634855",
"Expr1": "Photos/719192634855.JPG",
"Title": "LG DVDRW GH24NSC0 24X SATA without software Black Bare",
"Price": " 25 ",
"InStock": " 2 ",
"Category": "Electronics"
},
]
const productsEl = document.querySelector(".Sheet");
function getProducts() {
Sheet.forEach((product) => {
productsEl.innerHTML += `<div class="productContainer">
<div class="img">
<img src=${product.Expr1} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc">
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price">$<span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="UPCcode">${product.UPC}</div>
<div class="addToCart">
<button id="addToCart" > Add to Cart</button>
</div>
</div>`;
})
}
getProducts();
function Toys() {
//Show all objects with a Category of Toys
}
<div id="btnContainer">
<button class="btn active" > Show all</button>
<button class="btn"onclick="Electronics()">Electronics</button>
<button class="btn" onclick="Supplments()">Supplments</button>
<button class="btn" onclick="Toys()">Toys</button>
<button class="btn" onclick="Packing()">Packing</button>
<button class="btn" onclick="Other()">Other</button>
</div>
<div class="Sheet">
</div>
I have a file with thousand of objects, all with a category. I have buttons on the top of the page with a category as the HTML. How can I show these categories when someone presses the button. For example, I press the "Toys" button, all objects with the same category appear and the rest disappears.
This would also work. Using filter inside the getProducts function:
const Sheet = [{
"Code": "A-0-1",
"UPC": "4009803054728",
"Expr1": "Photos/4009803054728.JPG",
"Title": "U.S.S. Constitution",
"Price": " 31 ",
"InStock": " 7 ",
"Category": "Toys"
},
{
"Code": "C-1-1",
"UPC": "662248910376",
"Expr1": "Photos/662248910376.JPG",
"Title": "PS3 TOMB RAIDER TRILOGY",
"Price": " 29 ",
"InStock": " 4 ",
"Category": "Video Games"
},
{
"Code": "C-1-12",
"UPC": "719192634855",
"Expr1": "Photos/719192634855.JPG",
"Title": "LG DVDRW GH24NSC0 24X SATA without software Black Bare",
"Price": " 25 ",
"InStock": " 2 ",
"Category": "Electronics"
},
]
let selectedCategory = "All";
const productsEl = document.querySelector(".Sheet");
function getProducts(selectedCategory) {
let newHTML = "";
Sheet.filter(({
Category
}) => {
if (selectedCategory === undefined || selectedCategory === "All") {
return true;
}
return Category === selectedCategory
}).forEach((product) => {
newHTML += `<div class="productContainer" category-id=${product.Category}>
<div class="img">
<img src=${product.Expr1} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc">
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price">$<span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="UPCcode">${product.UPC}</div>
<div class="addToCart">
<button id="addToCart" > Add to Cart</button>
</div>
</div>`;
})
productsEl.innerHTML = newHTML;
}
getProducts(selectedCategory);
function onFilterClick(event) {
selectedCategory = event.target.value;
getProducts(selectedCategory);
}
<div id="btnContainer">
<button class="btn active" value="All" onclick="onFilterClick(event)">Show all</button>
<button class="btn" value="Electronics" onclick="onFilterClick(event)">Electronics</button>
<button class="btn" value="Supplments" onclick="onFilterClick(event)">Supplments</button>
<button class="btn" value="Toys" onclick="onFilterClick(event)">Toys</button>
<button class="btn" value="Packing" onclick="onFilterClick(event)">Packing</button>
<button class="btn" value="Other" onclick="onFilterClick(event)">Other</button>
</div>
<div class="Sheet">
</div>
I have this array of object that contains info string number array
I'm trying to print all the info of touristActivities inside an html <section>
I want to print first the information of stepOne in a section tag then the information of stepTwo in another section tag
touristActivities array can contain more the these two steps
my code below i can only print the info without the section
How can i print the info of each steps inside a different section for each step
example:
<section class="stepOne">
all step One information
</section>
<section class="stepTwo">
all step Two information
</section>
const database = [{
sectorId: 1,
sectorName: "السياحة",
sectorIcon: "icon-1.png",
sectorN: "tourism",
licenseTitle: ["إصدار ترخيص مرافق الإيواء السياحي", "الأنشطة السياحية"],
licenseDesc: ["تقديم خدمات الترخيص لنشاط الفنادق والشقق المخدومة والمخيمات والنزل وفنادق الكبائن والشاليهات.", "تقديم خدمات الترخيص لوكالات السياحة والسفر وتنظيم الرحلات السياحية وحجز وحدات الإيواء السياحي وتسويقها."],
licenseNum: ["7960", "7961"],
touristActivities: [
stepOne = {
subTitle: "إصدار رخصة استثمار للمستثمر الأجنبي",
description: "إصدار رخصة استثمار لغير السعوديين لمزاولة الأنشطة التجارية بما يتوافق مع الاشتراطات والمتطلبات المحددة.",
},
stepTwo = {
subTitle: "إصدار سجل تجاري",
description: "وثيقة قانونية تحتوي على بيانات التاجر والنشاط التابع له تمكنه من مزاولة نشاطه بتصريح رسمي وفق الاشتراطات والمتطلبات المحددة.",
}
]
},
{
sectorId: 2,
},
];
let title = document.querySelector(".title");
let rightSection = document.querySelector('.right');
function getInfo(id) {
for (let i = 0; i < database.length; i++) {
if (database[i].sectorId === parseInt(id)) {
title.innerHTML += `<img src='img/${database[i].sectorIcon}' alt='image'>`;
title.innerHTML += `<h2>${name}</h2>`;
for (let j = 0; j < database[i].touristActivities.length; j++) {
subTitle(database[i].touristActivities[j].subTitle);
description(database[i].touristActivities[j].description);
}
}
}
}
getInfo(1);
function subTitle(st) {
let subTitle = `<div class='subTitle'>
<h3>${st}</h3>
</div>`;
rightSection.innerHTML += subTitle;
}
function description(desc) {
let description = `
<div class="discription">
<div class="description-inner parent">
<div class="descText">
<img src="img/description.png" alt="desc">
<h4>وصف الخطوة</h4>
</div>
<i class="fas fa-angle-down"></i>
</div>
<div class="descInfo toggle">
<p>${desc}</p>
</div>
</div>
`;
rightSection.innerHTML += description;
}
<div class="container">
<div class="title">
</div>
<div class="right">
<div class="subTitle">
</div>
</div>
<div class="left"></div>
</div>
The thing is your functions directly modify the HTML. It is tightly coupled. So you lose quite a bit of control over the output. With your code the sequence of these function calls is important because the output will depend on the calls. E.g. first description() must be followed by time(). Now you want to wrap all this, but you have already written it to the DOM.
The sections span the content you want to generate from each step. Therefore, they have to wrap everything inside the for-loop there.
Instead of directly modifying the DOM, write the output of your functions to an array buffer. After the loop you will attach the whole content that you have created to the section element.
So you return the HTML from your functions, store it into the array buffer and once you looped over the section, you can combine/add the content with buffer.join('') and close it.
This way, you split the generators from the assembly code.
Here is a working example:
const database = [{
sectorId: 1,
sectorName: "السياحة",
sectorIcon: "icon-1.png",
sectorN: "tourism",
licenseTitle: ["إصدار ترخيص مرافق الإيواء السياحي", "الأنشطة السياحية"],
licenseDesc: ["تقديم خدمات الترخيص لنشاط الفنادق والشقق المخدومة والمخيمات والنزل وفنادق الكبائن والشاليهات.", "تقديم خدمات الترخيص لوكالات السياحة والسفر وتنظيم الرحلات السياحية وحجز وحدات الإيواء السياحي وتسويقها."],
licenseNum: ["7960", "7961"],
touristActivities: [
stepOne = {
subTitle: "إصدار رخصة استثمار للمستثمر الأجنبي",
description: "إصدار رخصة استثمار لغير السعوديين لمزاولة الأنشطة التجارية بما يتوافق مع الاشتراطات والمتطلبات المحددة.",
duration: "يوم واحد",
money: "٢٠٠٠",
year: "سنة - ٥",
concernedParty: ["وزارة الاستثمار"],
concernedPartyLogo: ["thumbnail_2.png"],
address: "<iframe src='https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3622.702432314261!2d46.721452214877665!3d24.771389754922634!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3e2efd91f30ee055%3A0x13c696d4f4a80ec3!2sHRSD%20Ministry!5e0!3m2!1sen!2slb!4v1639075198016!5m2!1sen!2slb' width='100%' height='180' style='border:0;' allowfullscreen='' loading='lazy'></iframe>",
phone: "١٩٩١١",
website: "https://hrsd.gov.sa/ar",
mail: "info#hrsd.gov.sa",
requirements: ["ألا يكون النشاط الاستثماري ضمن قائمة الأنشطة المستثناة من الاستثمار الأجنبي.", "أن تكون مواصفات المنتج مطابقة للمواصفات السعودية أو الخليجية أو الدولية.", "ألا يكون طالب الترخيص قد صدرت ضده قرارات نهائية بسبب مخالفات لأحكام النظام داخل المملكة أو خارجه.", "أن يلتزم طالب الترخيص بالشروط والتعهدات الملحقة بنموذج طلب الترخيص الاستثماري.", "أن يحقق منح الترخيص أهداف الاستثمار وتطبيق هذه الشروط والضوابط على طلبات تجديد الترخيص."],
needs: [
"صورة السجل التجاري وعقد التأسيس للمنشاة في بلدها مصدقة من الجهات المختصة والسفارة السعودية.",
"صورة من حجز الاسم التجاري من وزارة التجارة.",
"مشروع عقد تأسيس شركة ذات مسؤولية محدودة صورة من.",
"مشروع عقد التأسيس والنظام الأساسي للشركة المساهمة صورة من.",
"إرفاق قرار الشركاء رغبتهم في الاستثمار في المملكة موضحاً به أسماء الشركاء ورأس المال ونسبة ملكية كل شريك والمركز الرئيس للمنشأة وطبيعة النشاط.",
"تعيين المدير العام وتحديد صلاحياته مصدقًا من الجهات المختصة والسفارة السعودية.",
"صورة من جواز السفر للمدير العام.",
"صورة من الهوية الوطنية وبطاقة العائلة إذا كان أحد الشركاء يتمتع بالجنسية السعودية.",
"صورة من السجل التجاري لإثبات المهنة أو مستخرج من الأحوال المدنية.",
"تقديم موافقة مبدئية من الوزارات أو الهيئات المعنية إن كان النشاط يتطلب موافقة.",
"تقديم خطة عمل تفصيلية.",
"تقديم ميزانية للمنشاة طالبة الترخيص من خارج المملكة لفترة لا تقل عن 3 سنوات توضح سلامة الوضع المالي معتمدة من مكتب محاسبي ومصدقة من الجهاز المعني ومن سفارة المملكة.",
"إثبات القدرة المالية على الاستثمار بما يتناسب مع رأس مال المشروع وحصة كل شريك وبما يتناسب مع خطة العمل المقدمة."
],
linkTitle: "اضغط لاصدار الرخصة عبر المركز السعودي للأعمال",
link: "https://www.ncc.gov.sa/ar/Pages/default.aspx",
},
stepTwo = {
subTitle: "إصدار سجل تجاري",
description: "وثيقة قانونية تحتوي على بيانات التاجر والنشاط التابع له تمكنه من مزاولة نشاطه بتصريح رسمي وفق الاشتراطات والمتطلبات المحددة.",
duration: "حسب التصنيف",
money: "حسب التصنيف",
year: "",
concernedParty: ["وزارة التجارة"],
concernedPartyLogo: ["thumbnail_1.png"],
address: "<iframe src='https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3622.702432314261!2d46.721452214877665!3d24.771389754922634!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3e2efd91f30ee055%3A0x13c696d4f4a80ec3!2sHRSD%20Ministry!5e0!3m2!1sen!2slb!4v1639075198016!5m2!1sen!2slb' width='100%' height='180' style='border:0;' allowfullscreen='' loading='lazy'></iframe>",
phone: "١٩٩١١",
website: "https://hrsd.gov.sa/ar",
mail: "info#hrsd.gov.sa",
requirements: ["ألا يقل العمر عن 18 سنة.", "ألا يكون موظف حكومي.", "ألا يقل رأس المال عن 5000 ر.س.", "لا يشترط إصدار سجل فرعي إذا كان بنفس النشاط وبنفس المنطقة الإدارية."],
needs: [
"تقديم طلب لتأسيس الشركة إلكترونيًا عبر بوابة أعمال الشركات. aamal.sa",
"خطاب موقع من المؤسسين بتأسيس الشركة.",
"صورة بطاقة الأحوال.",
"ألا يقل رأس المال عن 500,000 ريال.",
"صورة من مشروع نظام الشركة الأساسي وعقد تأسيس الشركة.",
"مشروع نظام الشركة الأساسي وعقد تأسيس الشركة.",
"خطاب من الشركة بإصدار فرع شركة يتضمن مدينة الفرع ومدير الفرع مصدق من الغرفة التجارية.",
"التأكيد على المستثمر بالإيداع بعد انتهاء السنة المالية للشركة."
],
linkTitle: "اضغط لاصدار الرخصة عبر المركز السعودي للأعمال",
link: "https://www.ncc.gov.sa/ar/Pages/default.aspx",
}
]
},
{
sectorId: 2,
sectorName: "التعليم",
sectorIcon: "icon-2.png",
sectorN: "education",
licenseTitle: ["إصدار ترخيص مدرسة أهلية بمنهج وطني أو عالمي", "إصدار ترخيص مركز الإشراف والتدريب التربوي الأهلي", "إصدار ترخيص معاهد اللغات", "إصدار ترخيص منشأة تدريبية"],
licenseDesc: [],
licenseNum: ["7950", "7951"]
},
];
let title = document.querySelector(".title");
let subTitle = document.querySelector(".subTitle");
let rightSection = document.querySelector('.right');
function getInfo(id) {
for (let i = 0; i < database.length; i++) {
if (database[i].sectorId === parseInt(id)) {
title.innerHTML += `<img src='img/${database[i].sectorIcon}' alt='image'>`;
title.innerHTML += `<h2>${name}</h2>`;
const activities = database[i].touristActivities;
const contentBuffer = [];
for (let activity of activities) {
subTitle.innerHTML += `<h3>${activity.subTitle}</h3>`;
contentBuffer.push('<section>');
contentBuffer.push(description(activity.description));
contentBuffer.push(time(activity.duration));
contentBuffer.push(money(activity.money, activity.year));
contentBuffer.push(concerned(activity.concernedParty, activity.concernedPartyLogo, activity.address, activity.phone, activity.website, activity.mail));
contentBuffer.push(requirements(activity.requirements));
contentBuffer.push(needs(activity.needs));
contentBuffer.push(link(activity.linkTitle, activity.link));
contentBuffer.push('</section>');
}
rightSection.innerHTML = contentBuffer.join('');
}
}
}
getInfo(1);
function description(desc) {
return `
<div class="discription">
<div class="description-inner parent">
<div class="descText">
<img src="img/description.png" alt="desc">
<h4>وصف الخطوة</h4>
</div>
<i class="fas fa-angle-down"></i>
</div>
<div class="descInfo toggle">
<p>${desc}</p>
</div>
</div>
`;
}
function time(timeinfo) {
return `
<div class="time">
<div class="time-inner">
<div class="timeText">
<img src="img/time.png" alt="time">
<h4>المدة الزمنية</h4>
</div>
<img src="img/arrow.png" alt="arrow">
<p class="text">${timeinfo}</p>
</div>
</div>
`;
}
function money(m, y) {
return `
<div class="money">
<div class="money-inner">
<div class="moneyText">
<img src="img/money.png" alt="money">
<h4>المقابل المالي</h4>
</div>
<img src="img/arrow.png" alt="arrow">
<p class="text"><span>${m}</span> ر.س / <span>${y}</span> سنوات كحد أقصى</p>
</div>
</div>
`;
}
function concerned(a, b, m, p, w, e) {
return `
<div class="concerned">
<div class="concerned-inner parent">
<div class="concernedText">
<img src="img/jeha.png" alt="jeha">
<h4>الجهة المعنية</h4>
</div>
<i class="fas fa-angle-down"></i>
</div>
<div class="concernedInfo toggle">
<div class="concernedInfoContent">
<div class="box">
<img src="img/${b}" alt="logo" class="logo">
<h4 class="logoTitle">${a}</h4>
<p></p>
</div>
<div class="box">
<div class="locationTitle">
<img src="img/location.png" alt="location">
<h4>العنوان</h4>
</div>
<div class="map">${m}</div>
</div>
<div class="box">
<div class="phone">
<img src="img/phone.png" alt="phone">
<div class="phoneText">
<h4>الهاتف</h4>
مركز الاتصال الموحد s${p}
</div>
</div>
<div class="website">
<img src="img/almanasa-icon.png" alt="web">
<div class="websiteText">
<h4>المنصة الإلكترونية</h4>
${w}
</div>
</div>
<div class="mail">
<img src="img/bared.png" alt="mail">
<div class="webText">
<h4>البريد الإلكتروني</h4>
${e}
</div>
</div>
</div>
</div>
</div>
</div>
`;
}
function requirements(dt) {
return `
<div class="requirements">
<div class="requirements-inner parent">
<div class="requirementsText">
<img src="img/terms.png" alt="terms">
<h4>الاشتراطات</h4>
</div>
<i class="fas fa-angle-down"></i>
</div>
<div class="requirementsInfo toggle">
${dt.map(rq =>`<div class="inner-info">
<input type="checkbox" value="${rq}">
<p>${rq}</p></div>`).join("")}
</div>
</div>`;
}
function needs(dt) {
return `
<div class="needs">
<div class="needs-inner parent">
<div class="needsText">
<img src="img/needs.png" alt="needs">
<h4>المتطلبات</h4>
</div>
<i class="fas fa-angle-down"></i>
</div>
<div class="needsInfo toggle">
${dt.map(nd =>`<div class="inner-info">
<input type="checkbox" value="${nd}">
<p>${nd}</p></div>`).join("")}
</div>
</div>`;
}
function link(lt, li) {
return `
<div class="link">
<div class="link-inner parent">
<div class="linkText">
<img src="img/link.png" alt="link">
<h4>احصل على رخصتك عبر منصة الأعمال</h4>
</div>
<i class="fas fa-angle-down"></i>
</div>
<div class="linkInfo toggle">
${lt}
</div>
</div>`;
}
<div class="container">
<div class="title">
</div>
<div class="right">
<div class="subTitle">
</div>
</div>
<div class="left"></div>
</div>
Your code is not valid syntax.
Step one is inside an array and using '='
[step1 = {}, step2 = {}]
You will need to restructure it. Perhaps by adding a stepId field so you can mix it with other types.
[{stepId:'step1'},{stepId:'step2'},{not:'astep'}]
database.forEach(sector => {
const steps = sector.touristActivities.filter(activity=>activity.stepId !== undefined)
// Now use your `steps` to generate your sections.
steps.forEach(step=>{
const ele = document.createElement('section')
ele.className = step.stepId
ele.innerText = step.subTitle
// and so on
})
})
You can use Array.reduce() method to group activities by index:
let data = getDatabase();
// collect activities
let activities = [];
for (let sect of data) {
activities.push(sect.touristActivities);
}
// group by index
let groupedActivities = activities.reduce((groups, activities, index) => {
activities.forEach((step, i) => {
groups[i] = groups[i] || [];
groups[i].push(step);
});
return groups;
}, []);
// display in html <section>
groupedActivities.forEach((group, index) => {
let sec = document.createElement('section');
sec.innerHTML += `<hr><strong>Section step ${index + 1}</strong><br>`;
for (let act of group)
sec.innerHTML += `${act.subTitle}<br>`;
document.body.appendChild(sec);
});
function getDatabase() {
return [{
sectorId: 1,
sectorName: "sector Name",
licenseNum: ["7960", "7961"],
touristActivities: [
stepOne = {
subTitle: "sector1 stepOne",
description: "1 dsescription ",
},
]
},
{
sectorId: 2,
sectorName: "sector Name",
licenseNum: ["7960", "7961"],
touristActivities: [
stepOne = {
subTitle: "sector2 stepOne",
description: "sector2 dsescription",
},
stepTwo = {
subTitle: "sector2 stepTwo",
description: "sector2 dsescription",
},
]
},
{
sectorId: 3,
sectorName: "sector Name",
licenseNum: ["7960", "7961"],
touristActivities: [
stepOne = {
subTitle: "sector3 stepOne",
description: "sector3 dsescription",
},
stepTwo = {
subTitle: "sector3 stepTwo",
description: "sector3 dsescription",
},
stepThree = {
subTitle: "sector3 stepThree",
description: "sector3 dsescription",
}
]
},
];
}
If you are doing a lot of complex queries on object structure then you can use jsonpath library.
<script src="https://cdn.jsdelivr.net/npm/jsonpath#1.1.1/jsonpath.min.js"></script>
<script>
let activities = jsonpath.query(database, '$..touristActivities');
</script>
[
{
"id": 0,
"owner": {
"id": 0,
"email": "",
"username": "",
"profile": "",
"description": "",
"followers": 0,
"following": 0
},
"title": "",
"content": "",
"image_urls": [
"image_url1",
"image_url2",
"image_url3", ...
],
"liked_people": [
1,
2,
3, ...
],
"like_count": 0,
"comment_count": 0,
"view_count": 0,
"tag" : [
"tag1",
"tag2",
"tag3", ...
],
"created_at": "",
"comment_preview": [
{
"comment_id": 0,
"owner": {
"id": 0,
"email": "",
"username": "",
"profile": "",
"description": "",
"followers": 0,
"following": 0
},
"content": "",
"created_at": ""
}, ...
]
}, .....
]
This is api what feed and detail data.
I am developing SNS.
I get this data
and I want to create feed list what having 2 comments
but comments is may or may not be exist.
So how to append this comments to html?
Here is example code
Please add comments html is .feedComment.
const getFeed = (id) => {
$.ajax({
url: `BASE_URL/feed/postList`,
type: 'GET',
success: function(res) {
res.map(({id, owner, image_urls, title, content, tag, comment_preview}) => {
$('.feedArea').append(`
<div class='feed'>
<div class='feedHead'>
<div class='postmanProfile'>
<img src= "${owner.image}">
</div>
<div class='postmanName'>
<div class= 'postmanNameText'>${owner.username}</div>
</div>
</div>
<div class='disuniteLine'>
<hr>
</div>
<div class="feedThumbanil">
<div class="thumbanilImg">
<a href="detailFeed.html?id=${id}">
<img class="ImgArea" src="${image_urls}" alt="">
</a>
</div>
</div>
<div class="disuniteLine">
<hr>
</div>
<div class='feedLike_And_Comment'>
<div class='LikeIconImg like-${id}' feedId="${id}">
</div>
<div class="CommentIconImg">
<img class="commentImg" src="/picture/Icon/chat-box.png" alt="#">
</div>
<div class="viewMoreArea">
<img class="view_more" src="/picture/Icon/more.png">
</div>
</div>
<div class='title'>
<h2>
${title}
</h2>
</div>
<div class='content'>
<span>
${content}
</span>
</div>
<div class='tag'>
<h4>
${tag}
</h4>
</div>
<div class="feedComment">
// What should I do?
</div>
</div>
`);
})
},
error : function(err){
console.log(err);
},
async: false
})
}
I am time-limited life.
If I don't solve this, I might die.
Assuming your ajax works, you basically need this
<div class="feedComment">
${Object.keys(comment_preview[0].owner)
.map(key => (key+":"+comment_preview[0].owner[key]))
}
</div>
const res = [{ "id": 0, "owner": { "id": 0, "email": "", "username": "", "profile": "", "description": "", "followers": 0, "following": 0 }, "title": "", "content": "", "image_urls": [ "image_url1", "image_url2", "image_url3" ], "liked_people": [ 1, 2, 3 ], "like_count": 0, "comment_count": 0, "view_count": 0, "tag": [ "tag1", "tag2", "tag3" ], "created_at": "", "comment_preview": [{ "comment_id": 0, "owner": { "id": 0, "email": "bla#bla.com", "username": "User x ", "profile": "x profile", "description": "Desc", "followers": 0, "following": 0 }, "content": "Is this a feed comment?", "created_at": "" }] }]
function format(res) {
res.forEach(({
id,
owner,
image_urls,
title,
content,
tag,
comment_preview
}) => {
$('.feedArea').append(`
<div class='feed'>
<div class='feedHead'>
<div class='postmanProfile'>
<img src= "${owner.image}">
</div>
<div class='postmanName'>
<div class= 'postmanNameText'>${owner.username}</div>
</div
</div>
<div class='disuniteLine'>
<hr>
</div>
<div class="feedThumbanil">
<div class="thumbanilImg">
<a href="detailFeed.html?id=${id}">
<img class="ImgArea" src="${image_urls}" alt="">
</a>
</div>
</div>
<div class="disuniteLine">
<hr>
</div>
<div class='feedLike_And_Comment'>
<div class='LikeIconImg like-${id}' feedId="${id}">
</div>
<div class="CommentIconImg">
<img class="commentImg" src="/picture/Icon/chat-box.png" alt="#">
</div>
<div class="viewMoreArea">
<img class="view_more" src="/picture/Icon/more.png">
</div>
</div>
<div class='title'>
<h2>
${title}
</h2>
</div>
<div class='content'>
<span>
${content}
</span>
</div>
<div class='tag'>
<h4>
${tag}
</h4>
</div>
<div class="feedComment">
${Object.keys(comment_preview[0].owner)
.map(key => (key+":"+comment_preview[0].owner[key]))
}
</div>
`);
})
}
format(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="feedArea"></div>