简体   繁体   中英

Count the subtotal from list select option, based on clicked (' active ') element

This is my goal: Before anything clicked || After user select the item that they want

After i done some research, i was able to make this with vue.js
https://jsfiddle.net/Hanstopz/Lcnxtg51/10/

But, when i trid to create this with Plain javascript, i was stuck

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Form pesanan</title> <style> @import url(https://fonts.googleapis.com/css?family=Cookie); [v-cloak] { display: none; } *{ margin:0; padding:0; } body{ font:15px/1.3 'Open Sans', sans-serif; color: #5e5b64; text-align:center; } a, a:visited { outline:none; color:#389dc1; } a:hover{ text-decoration:none; } section, footer, header, aside, nav{ display: block; } form{ background-color: #61a1bc; border-radius: 2px; box-shadow: 0 1px 1px #ccc; width: 400px; padding: 35px 60px; margin: 50px auto; } form h1{ color:#fff; font-size:64px; font-family:'Cookie', cursive; font-weight: normal; line-height:1; text-shadow:0 3px 0 rgba(0,0,0,0.1); } form ul{ list-style:none; font-size:20px; font-weight:bold; text-align: left; margin:20px 0 15px; } form ul li{ padding:20px 30px; background-color:#f0f0f0; margin-bottom:8px; box-shadow:0 1px 1px rgba(0,0,0,0.1); cursor:pointer; } form ul li span{ float:right; } /* ini bagian v-bind 'active' (menambahkan class ini ke li) */ .active{ color: white; background-color: darkgreen; } div.total{ border-top:1px solid rgba(255,255,255,0.5); padding:15px 30px; font-size:20px; font-weight:bold; text-align: left; color:#fff; } div.total span{ float:right; } </style> </head> <body> <form id="main"> <h1>Menu kami</h1> <ul id="menu"> <!-- {{service.name}} <span>{{service.price | currency}}</span> --> </ul> <div class="total"> Total harga: <!-- Total: <span>{{total() | currency}}</span> --> </div> </form> <script> const menu = [ { name: 'Cappucino', price: 35000, active: true }, { name: 'Green tea latte', price: 40000, active: false }, { name: 'Fish and chips', price: 50000, active: false }, { name: 'Tuna sandwich', price: 30000, active: false }, { name: 'Mineral water', price: 8000, active: false }, { name: 'French fries', price: 18000, active: false } ] menu.forEach((menu, price) => { document.getElementById('menu').innerHTML += "<li>" + menu.name + "<span>" + "Rp " + menu.price + "</span>" + "</li>" }); </script> </body> </html>

i managed to create the display from array, but i get confused on how do i add an active class when i click on the list and a function to calculate all active element... Anyone please help me.

{UPDATE} after i combined the answer from Nabir Abbas, i can select and toggle between active and not active element. But i wanna make a total that can be counted whenever it has an active element. The price would be taken from the array based on active link... so i tried this

 function totalCount() { if ($("li").hasClass("active")) { document.getElementById("subtotal").innerHTML = 0 + $(menu.price); }}

but it does not seems right, can anyone help me?

This should work:

const menu = [{
    id: 1,
    name: 'Cappucino',
    price: 35000,
    active: true
  },
  {
    id: 2,
    name: 'Green tea latte',
    price: 40000,
    active: false
  },
  {
    id: 3,
    name: 'Fish and chips',
    price: 50000,
    active: false
  },
  {
    id: 4,
    name: 'Tuna sandwich',
    price: 30000,
    active: false
  },
  {
    id: 5,
    name: 'Mineral water',
    price: 8000,
    active: false
  },
  {
    id: 6,
    name: 'French fries',
    price: 18000,
    active: false
  }
]

menu.forEach((menu, price) => {
    const li = document.createElement('li')
  li.innerHTML = `${menu.name}<span>Rp ${menu.price}</span>`
  li.addEventListener('click', e => {
    li.classList.toggle('active')
    console.log('Active lements', getActiveCount())
  })
  
  document.getElementById('menu').append(li)
  
});

function getActiveCount() {
    const activeListItems = document.querySelectorAll('#menu li.active')
  return activeListItems.length
}

Here we are adding the event listener to per element on the go before appending them to the parent. Also, notice we are using classList.toggle which removes the active class if it exists on the list item and adds it if it doesn't

Edit 10/7/2020

To get the total price of the active elements, first you have to add the item price as an attribute to per li, you can use the following function:

so the above code becomes:

menu.forEach(item => {
    const li = document.createElement('li')
  li.innerHTML = `${menu.name}<span>Rp ${menu.price}</span>`
  li.setAttribute('data-price', item.price)
  li.addEventListener('click', e => {
    li.classList.toggle('active')
    console.log('Active lements', getActiveCount())
  })
  
  document.getElementById('menu').append(li)
  
});

Then:

function getTotalPrice() {
  const activeItems = document.querySelectorAll('#menu li.active')
  return activeItems.length ? Array.from(activeItems).reduce((acc, elem) => acc+=elem.getAttribute('data-price'), 0): 0
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM