Johny1995QQ
Johny1995QQ

Reputation: 19

Rendering HTML cards via JavaScript problem

So basically what's the idea of my code: user inputs image URL, price, and description and click's 'create card' and then it should create a card.

All products that user create are saved in the 'productsArr' array;

After the user click's create card it should render HTML from the 'productsArr' array and display all the cards, but for some reason, it only creates a single card and then copies's it into HTML?

May someone please tell me what's wrong with my JS code?

PS sorry for my English

let productsArr = [];

let product = {
    image: null,
    price: null,
    description: null,
    id: null
}

function getInfo() {
    product.image = document.getElementById("image").value;
    product.price = document.getElementById("price").value;
    product.description = document.getElementById("description").value;
    product.id = document.getElementById("id").value;
}

function render() {
    let arr = productsArr;
    for (let i = 0; i < arr.length; i++) {
        let str = '';
        str = ' <div class="item_body" data-id="i">\n' +
            '            <img id="img" src="' + arr[i].image + '" alt="#">\n' +
            '            <div class="description">' + arr[i].description + '</div>\n' +
            '            <div class="price">' + arr[i].price + '</div>\n' +
            '            <input type="button" value="В коризну">' +
            '       </div>'
        document.getElementById('all_products').innerHTML += str;
        arr = [];
    }
}

function pushIt() {
    getInfo();
    productsArr.push(product);
    render(productsArr);
    product = {
        image: null,
        price: null,
        description: null,
        id: null
    }
}

function sortByPrice() {
    productsArr.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
}

console.log(productsArr)
.container {
    max-width: 2000px;
    margin: 0 auto;
    display: flex;
}

.form {
    height: 420px;
    width: 30%;
    padding: 50px;
    background: #73AFBA;
    border-radius: 10%;
}
label {
    display: flex;
    flex-direction: column;
}
.products-section {
    width: 70%;
}
.products-section-header {
    display: flex;
    justify-content: center;
    align-items: center;
}
.products {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    margin-left: 50px;
}

input {
    width: 100%;
    margin: 10px 0;
}
.item_body {
    width: 30%;
    padding: 10px;
    margin: 20px;
    height: 400px;
    border: #1C2E3D solid 1px;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
    text-align: center;
}
.item_body img {
    max-width: 80%;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link href="styles.css" rel="stylesheet">
    <title>Title</title>
</head>
<body>
<div class="container">
    <div class="form">
        <label>
            <p>Image</p>
            <input id="image" type="text" name="image">
            <p>Price</p>
            <input id="price" type="text" name="price">
            <p>Description</p>
            <input id="description" type="text" name="description">
            <p>Id</p>
            <input id="id" type="text" name="id">
            <input type="submit" value="Create card" onclick="pushIt()">
        </label>
    </div>
    <div class="products-section">
        <div class="products-section-header">
            <input type="button" name="sortByPrice" value="Sort by price" onclick="sortByPrice()">
        </div>
        <div class="products" id='all_products'></div>
    </div>
</div>
<script src="script.js"></script>
</body>
</html>

Upvotes: 0

Views: 815

Answers (1)

Yash Maheshwari
Yash Maheshwari

Reputation: 2412

As you are pushing the products in the productsArr. So instead of passing the productsArr to render function pass the current product to render function. In this way, you don't need to use the for loop in the render function and you can use the productsArr for future use as well.

So your function will look like:

function pushIt() {
    getInfo();
    productsArr.push(product);
    render(product);
    product = {
        image: null,
        price: null,
        description: null,
        id: null
    }
}

And your render function will become:

function render(product) {
        let str = '';
        str = ' <div class="item_body" data-id="i">\n' +
            '            <img id="img" src="' + product.image + '" alt="#">\n' +
            '            <div class="description">' + product.description + '</div>\n' +
            '            <div class="price">' + product.price + '</div>\n' +
            '            <input type="button" value="В коризну">' +
            '       </div>'
        document.getElementById('all_products').innerHTML += str;
}

Upvotes: 1

Related Questions