Home > Mobile >  Unpacking object to display it's content with innerHTML
Unpacking object to display it's content with innerHTML

Time:03-13

On this page you can order tickets by clicking on the list items. Clicked items get grouped and then put in an empty container on the page. I added a sample view to clarify what the result should be.

At this point I am stuck. I’m able to insert objects, but I don’t know how to unpack whats inside the object. That should be the tickets one clicked. Hopefully someone here can point me in the right direction to solve this.

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>Page Title</title>
    <style>
        /*  Styling bullets list items */
        li {
            list-style: none;
        }

        li:before {
            content: "\1F3B8";
            margin-right: 10px;
        }
        /* Styling for tickets ordered */
        #order {
            background-color: #b0c4de;
            font-size: 120%;
        }
        .sample {
            background-color: #b0c4de;
            font-size: 120%;
        }
    </style>
</head>
<body>

<p>Here you'll find the prices for the tickets:</p>

<ul>
    <li onclick="push(tckt1)">Saturday: €110</li>
    <li onclick="push(tckt2)">Sunday: €110</li>
    <li onclick="push(tckt3)">Monday: €110</li>
    <li onclick="push(tckt4)">Weekend: €230</li>
</ul>
<div id="order">

</div>
<br>
// This is a sample of how the output should look.
<div >
    Your order:<br>
    3 Weekend-tickets à €230 = € 690<br>
    1 Sunday-tickets à €110 = € 110<br>
    Totaalbedrag: €800 - 10% korting à €80 = €720
</div>
<script>
    const order = document.getElementById("order")
    let tickets = [];

    const tckt1 = {id: 1, name: "Saturday-tickets à €110", price: 110};
    const tckt2 = {id: 2, name: "Sunday-tickets   à €110", price: 110};
    const tckt3 = {id: 3, name: "Monday-tickets   à €110", price: 110};
    const tckt4 = {id: 4, name: "Weekend-tickets  à €230", price: 230};

    // Push object in array tickets
    function push(temp){
    tickets.push(temp);
    let res = tickets.reduce(function (x,cur){
    let item = cur.id   cur.name   cur.price
    if (!x[item]) x[item] = 0;
    x[item] = x[item]   1
    return x
    }, {})
    let results = []

    for (const key in res) {
    const count = res[key];
    const id = key.slice(0, 1)
    const day = key.slice(1, 24)
    const price = key.slice(24)
    results.push({
    id: id,
    name: day,
    price: price,
    count: count
    })
    }
    console.log(results)
    order.innerHTML =results[0];
    }
</script>
</body>
</html>

CodePudding user response:

First: it is generally not a good idea to use inline event handlers. The next snippet uses event delegation to handle the clicks.

Second, i have refactored your code a bit. For identifying the originator of a click, it uses a data-attribute. After clicking the accessory ticket definition is pushed to an array (savedTickets). That array is aggregated to an Object (orders) containing the total values, using ticket definitions name property as keys). From that, the result (div#orders) is filled, using insertAdjacentHTML. Text is aggregated using template literals.

Third: I've used dutch language ;)

document.addEventListener(`click`, pushTicketAndShowResult);
const [savedTickets, tickets, discount] = initializeValues();

function pushTicketAndShowResult(evt) {
  if (!evt.target.dataset.ticket) {
    return;
  }

  const ticket = tickets[`tckt${evt.target.dataset.ticket}`];
  savedTickets.push(ticket);
  const orders = savedTickets.reduce((acc, t) => {
    acc[t.name] = acc[t.name] || {};
    acc[t.name].n = (acc[t.name].n || 0)   1;
    acc[t.name].total = acc[t.name].n * t.price;
    return acc;
  }, {});

  const result = document.querySelector(`#orders`);
  const total = Object.values(orders).reduce( (acc, o) => acc   o.total, 0);
  const discountAmount = total * discount/100; 
  const totalWithDiscount = total - discountAmount;
  const yourOrders = Object.entries(orders)
    .map( ([name, val]) => `${val.n} ${name} = €${val.total},--`)
    .join(`<br>`)    
    
  result.textContent = ``;
  result.insertAdjacentHTML(`beforeend`, `<b>Uw bestelling</b><br>${
    yourOrders}<br>Totaalbedrag: €${total},--<br>Korting ${
      discount}% = €${discountAmount},--<br><b>U betaalt €${
        totalWithDiscount},--</b>`);
}

function initializeValues() {
  return [
    [], {
      tckt1: {
        id: 1,
        name: "zaterdag-ticket(s) à €110,--",
        price: 110
      },
      tckt2: {
        id: 2,
        name: "zondag-ticket(s) à €110,--",
        price: 110
      },
      tckt3: {
        id: 3,
        name: "maandag-ticket(s) à €110,--",
        price: 110
      },
      tckt4: {
        id: 4,
        name: "weekend-ticket(s) à €230,--",
        price: 230
      }
    },
    10
  ];
}
body {
  font: normal 12px/15px verdana, arial;
}

li {
  list-style: none;
  cursor: pointer;
}

li:before {
  content: "\1F3B8";
  margin-right: 10px;
}

#order {
  background-color: #b0c4de;
  font-size: 120%;
}

.sample {
  background-color: #b0c4de;
  font-size: 120%;
}
<p>Ticketprijzen. Klik op een prijs om te bestellen:</p>

<ul>
  <li data-ticket="1">Zaterdag: €110,--</li>
  <li data-ticket="2">Zondag: €110,--</li>
  <li data-ticket="3">Maandag: €110,--</li>
  <li data-ticket="4">Weekend: €230,--</li>
</ul>
<div id="orders">
</div>

  • Related