I am developing shopping cart application in MVC 4 where I need to update the amount on changing the cart quantity.
#foreach (var item in Model)
{
<tr>
<td>#item.ProductId</td>
<td>#item.Product.ProductName</td>
<td id="PriceBx">#item.Product.UnitPrice</td>
<td id="QtyBx" oninput="calculate()">#Html.TextBox("QuantityBox", item.Quantity, new { style = "width:50px" })</td>
<td id="result">#String.Format("{0:c}", Convert.ToDouble(item.Quantity) * Convert.ToDouble(item.Product.UnitPrice))</td>
</tr>
}
In this I need to update the total when the value in QuantityBox is changed.
I tried using Javascript
<script type="text/javascript">
function calculate()
{
var myBox1 = document.getElementById('QtyBx').value;
var myBox2 = document.getElementById('PriceBx').value;
var result = document.getElementById('result');
var myResult = myBox1 * myBox2;
result.innerHTML = myResult;
}
Generating multiple elements using a foreach then using id attribute for elements inside it is never a good idea because element id has to be unique per HTML page.
Try to append the product-id to the element id:
#foreach (var item in Model)
{
<tr>
<td>#item.ProductId</td>
<td>#item.Product.ProductName</td>
<td id="PriceBx#(item.ProductId)">#item.Product.UnitPrice</td>
<td id="QtyBx#(item.ProductId)" oninput="calculate(#(item.ProductId))">#Html.TextBox("QuantityBox", item.Quantity, new { style = "width:50px" })</td>
<td id="result#(item.ProductId)">#String.Format("{0:c}", Convert.ToDouble(item.Quantity) * Convert.ToDouble(item.Product.UnitPrice))</td>
</tr>
}
And in your Javascript:
function calculate(itemId)
{
var myBox1 = parseInt(document.getElementById('QtyBx' + itemId).value, 10);
var myBox2 = parseFloat(document.getElementById('PriceBx' + itemId).value);
var result = document.getElementById('result' + itemId);
var myResult = myBox1 * myBox2;
result.innerHTML = myResult;
}
(I took the liberty to explicitly convert the values of your inputs to int and float respectively)
first of all, some remarks:
you're using an id in your HTML and you're repeating it through your Model, this breaks the rule that one page should have unique id's
You're not using any javascript framework, though pure javascript is a way to accomplish what you need, but in the future you might have some cross-broser issues when performing more advance tasks
you have an onInput in your td, but it should be in the checkbox it self
you can easily use your own textbox markup:
<td id="QtyBx" oninput="calculate()">
#Html.TextBox("QuantityBox", item.Quantity, new { style = "width:50px" })
</td>
<td id="result">
...
</td>
change to:
<td class="quantity">
<input type="number" id="QuantityBox_#item.Product.ProductId"
value="#item.Quantity"
data-unitprice="#item.Product.UnitPrice"
data-productid="#item.Product.ProductId"
onchange="calculate(this)" />
</td>
...
and, using jQuery (to handle the data- easier) should be something like:
function calculate(elm) {
var chk = $(elm), // the checkbox
vlu = chk.val(), // the current qty value
pid = chk.data("productid"), // product id
unt = chk.data("unitprice"), // unit price
res = $(".result_" + pid), // the result for this product
tot = vlu * unt; // total
res.text("$" + tot); // write the value
}
a live example: https://jsbin.com/gafaja/edit?html,js,output
if you still wanna learn/do it in plain javascript:
function calculate(elm) {
var vlu = elm.value, // the current qty value
pid = elm.getAttribute("data-productid"), // product id
unt = elm.getAttribute("data-unitprice"), // unit price
res = document.getElementsByClassName("result_" + pid), // the result for this product
tot = vlu * unt; // total
res[0].innerHTML = "$" + tot; // write the value
}
one more thing...
don't add style to the elements, just add a stylesheet as:
<style>
.quantity input { width:50px; }
</style>
Related
Here I am trying to add two decimal values in line var totalSum = (grandTotal + getShippingCost).toFixed(3); and put the value in var getSumTd = $("tr#sumTr").find("span#sumSpan");.But the problem is that var totalSum = (grandTotal + getShippingCost).toFixed(3); throws an error saying Uncaught TypeError: value.toFixed is not a function.
Any help with my code will be great help.
Below is my script
<script>
$('button#value-plus').on('click', function () {
debugger;
var divUpd = $(this).closest("tr").find('#qnty');
var subtotalcontainer = $(this).closest("tr").find('span#subtotal');
var mainGrandTotalcontainer = $("tr#mainGtTr").find("#mainGt");
var mainGtVal = parseFloat($("tr#mainGtTr").find('span#shippingCost').text());
var getSumTd = $("tr#sumTr").find("span#sumSpan");
var getShippingCost = parseFloat($("tr#mainGtTr").find('span#mainGt1').text());
var bklId = $(this).closest("tr").find('#pid').val();
var url = "/Product/incrementcart";
$.getJSON(url, { prdid: bklId }, function (data) {
debugger;
divUpd.val(data.qty);
var subTotal = data.qty * data.price;
subtotalcontainer.text(subTotal.toFixed(2));
var grandTotal = (mainGtVal + data.price).toFixed(3);
mainGrandTotalcontainer.text(grandTotal);
var totalSum = (grandTotal + getShippingCost).toFixed(3);
getSumTd.text(totalSum);
}).success(function () {
debugger
var url = "/Product/cartupdate";
$.get(url, function (data) {
debugger;
$(".shopping_button").html(data);
})
});
});
Below is my HTML
<tbody>
#foreach (var item in Model)
{
<tr>
#Html.HiddenFor(model => item.ProductId, htmlAttributes: new { #id = "pid" })
<td data-title="Product Image & name" class="t_md_align_c">
<img src="images/quick_view_img_10.jpg" alt="" class="m_md_bottom_5 d_xs_block d_xs_centered">
#Html.DisplayFor(modelItem => item.ProductName)
</td>
<td data-title="Stock">
#Html.DisplayFor(modelItem => item.Instock)
</td>
<td data-title="Price">
<p class="f_size_large color_dark">$#Html.DisplayFor(modelItem => item.ProductPrice)</p>
</td>
<td data-title="Quantity">
<div class="clearfix quantity r_corners d_inline_middle f_size_medium color_dark m_bottom_10">
<button class="bg_tr d_block f_left" data-direction="down" id="value-minus">-</button>
<input type="text" name="" id="qnty" readonly value="#item.Quantity" class="f_left">
<button class="bg_tr d_block f_left" data-direction="up" id="value-plus">+</button>
</div>
</td>
<td data-title="Subtotal">
<p class="f_size_large fw_medium scheme_color">$<span id="subtotal">#Html.DisplayFor(modelItem => item.Total)</span></p>
</td>
<td data-title="Remove">
<i class="fa fa-times f_size_medium m_right_5"></i>Remove<br>
</td>
</tr>
}
<tr id="mainGtTr">
<td colspan="4" class="v_align_m d_ib_offset_large t_xs_align_l">
<div class="d_ib_offset_0 d_inline_middle half_column d_xs_block w_xs_full m_xs_bottom_5">
<button class="button_type_6 bg_scheme_color f_size_large r_corners tr_all_hover color_light m_bottom_20">Check Out </button>
</div>
<p class="fw_medium f_size_large t_align_r scheme_color p_xs_hr_0 d_inline_middle half_column d_ib_offset_normal d_xs_block w_xs_full t_xs_align_c">Grand Total:</p>
</td>
<td colspan="2" class="v_align_m">
<p class="fw_medium f_size_large scheme_color m_xs_bottom_10">$<span id="mainGt">#ViewBag.SubTotal</span></p>
<p style="font-style:oblique">Include <i class="fa fa-rupee"></i> <span id="shippingCost">#ViewBag.ShipingCost</span> shipping cost</p>
</td>
</tr>
#{
var sum = ViewBag.SubTotal + ViewBag.ShipingCost;
}
<tr id="sumTr">
<td>
<span id="sumSpan">#sum</span>
</td>
</tr>
</tbody>
toFixed() method formats a number. The current value is of type string and instead of arithmetic addition, string concatenation is happening. Convert those to number before adding:
Change:
var totalSum = (grandTotal + getShippingCost).toFixed(3);
To
var totalSum = (Number(grandTotal) + Number(getShippingCost)).toFixed(3);
Only float, int value have toFixed. controle your variable and see which type are they.
console.log(("4" + 5).toFixed(3)); // error
console.log((5 + 5).toFixed(3)); // yeep its working
toFixed method is not available on non-number values. you need to parse value to Number first than you can use toFixed method.
let str = `123.123456`
console.log(Number(str).toFixed(3))
console.error(str.toFixed(3))
Check the data type of both the variables. They should be numeric and not strings. The method toFixed will not work for other data types. Also make sure when you convert the string to number, the value in string is internally a number like ‘22’ and not ‘hello’ as converting it to number may give you NaN and your program may fail.
.toFixed() is only a function of a number and returns a string. By using toFixed in multiple assignments, you're turning a number into a string, concatenating multiple strings together, then trying to do a numerical operation on a string.
The following code will give an error.
var grandTotal = (mainGtVal + data.price).toFixed(3); // grandTotal is a string
var totalSum = (grandTotal + getShippingCost).toFixed(3); // grandTotal + getShippingCost is a String, which doesn't have the toFixed function
If you need to avoid floating-point errors, then convert the string to a number before adding it to another number, for example:
var grandTotal = (mainGtVal + data.price).toFixed(3);
grandTotal = Number.parseFloat(grandTotal);
var totalSum = (grandTotal + getShippingCost).toFixed(3);
Otherwise, wait until you're done with your calculations to use toFixed to round to the number of decimal places you want to display, for example:
var grandTotal = mainGtVal + data.price;
var totalSum = (grandTotal + getShippingCost).toFixed(3);
grandTotal = grandTotal.toFixed(3);
I have the following HTML table:
<table id="review-total">
<tbody><tr class="wlp">
<td class="left-cell">WLP Total</td>
<td>199.00</td>
</tr>
<tr class="tax">
<td class="left-cell">GST</td>
<td>19.90</td>
</tr>
<tr class="net">
<td class="left-cell">Order Total</td>
<td class="net-price">$218.90</td>
</tr>
</tbody>
</table>
I'm trying to loop through this table and retrieve the values i.e
199.00, 19.90 and $218.90 I have the following code:
var reviewTotal = document.getElementById('review-total');
for (var i = 1; i < reviewTotal.rows.length; i++) {
if (reviewTotal.rows[i].cells.length) {
wlpTotal = (reviewTotal.rows[i].cells[1].textContent.trim());
gstAmount = (reviewTotal.rows[i].cells[3].textContent.trim());
totalOrderAmount = (reviewTotal.rows[i].cells[5].textContent.trim());
}
}
I'm having a small issue trying to retrieve those values specified above, at present the error I get is textContent is undefined.
Can someone show me how I should go about retrieving those values, unfortunately I'm not strong in Javascript.
You have 3 rows and each row has only 2 cells. The 3 and 5 indices are undefined and undefined doesn't have .textContent property.
If you want to store the values by using specific variable names, you remove the loop and select the target elements manually:
var wlpTotal = reviewTotal.rows[0].cells[1].textContent.trim();
var gstAmount = reviewTotal.rows[1].cells[1].textContent.trim();
var totalOrderAmount = reviewTotal.rows[2].cells[1].textContent.trim();
If you want to store the values in an array, you can code:
var values = [].map.call(reviewTotal.rows, function(row) {
return row.cells[1].textContent.trim();
});
By using ES2015's Destructuring Assignment you can also extract the array's elements:
var [wlpTotal, gstAmount, totalOrderAmount] = values;
First:the index start the 0 either row or cell.
Secend:get value in the tag to use innerText or innerHTML ,The code following:
var reviewTotal = document.getElementById('review-total');
for (var i = 0; i < reviewTotal.rows.length; i++)
{
if (reviewTotal.rows[i].cells.length>1)
{
wlpTotal = (reviewTotal.rows[i].cells[1].innerText);
}
}
There is a table displaying model entries, with each field designated a unique div id combining a keyword and each row's ID. When the user enters a number in the table's input column, a script is supposed to: get the locations of the cells on the same row; and change the values of two predetermined cells based on the values of the other cells.
It seems that tests are successful until the final updating. I've tried using .val(), .value, and .html(), and the resultant cells go blank, or show 0 if the script is error-free. Would someone please post the correct jQuery command and why it works? Many thanks in advance.
The table:
<table id="dt_Positions" class="table table-striped">
<thead>
<tr>
<th class="text-center">Month</th>
<th class="text-center">Owed</th>
<th class="text-center">Bought</th>
<th class="text-center">Total Position</th>
<th class="text-center">Non-Fixed</th>
<th class="text-center">Fixed</th>
<th class="text-center">Fixed Position</th>
<th class="text-center">Proposed</th>
</tr>
</thead>
<tbody>
#if (Model.Forecasts.Any())
{
foreach (var record in Model.Summaries)
{
<tr>
<td id="nmonth#(record.fID)" align="center">#String.Format("{0:d}", #record.Month)</td>
<td id="ntotal#(record.fID)" align="center">#record.NTotal</td>
<td id="nbought#(record.fID)" align="center">#record.NBought</td>
<td id="ntposition#(record.fID)" align="center">#record.NTotalPosition</td>
<td id="nvariable#(record.fID)" align="center">#record.NVariable</td>
<td id="nfixed#(record.fID)" align="center">#record.NFixed</td>
<td id="nfposition#(record.fID)" align="center">#record.NFPosition</td>
<td id="ninput#(record.fID)" align="center"><input class="nInput" type="number" name="quantity" min="1" max="50000"></td>
</tr>
}
}
</tbody>
</table>
The script:
#section Scripts
{
<script src="~/Scripts/jquery-2.1.3.js"></script>
<script type="text/javascript" language="javascript">
$(function () {
$('[id^=ninput]').keyup(function (e) {
var $id = $(this).attr('id');
var $i = $(this);
var $idNum = $id.slice(6);
var $tp = $('#ntposition' + $idNum);
var $fp = $('#nfposition' + $idNum);
var $nt = $('#ntotal' + $idNum);
var $nh = $('#nbought' + $idNum);
var $f = $('#nfixed' + $idNum);
//The lines below appear to be the hiccup
$tp.val($nh.val() + $i.html() - $nt.val());
$fp.val($nh.val() + $i.html() - $f.val());
debugger;
});
});
</script>
}
EDIT: Examples of ids returning "NaN" are:
ntotal = 29, nbought = 5, ntposition = -24, nvariable = 3, nfixed = 26, nfposition = -21, with all appearing to be int from testing the View, but ntotal, nbought, and nfixed showing "NaN" in the console.log and resulting in "NaN" appearing in the test View after an ninput = 5.
$i is the textbox, so to get its value you need to use $i.val(). The other elements are table cells, so to get or set the values you need .text(), not .val(). However you over complicating code by using id attributes. Instead, remove then and use relative selectors
$('input').keyup(function() { // or $('.nInput').keyup
var i = Number$(this).val());
var cells = $(this).closest('tr').children('td');
var tp = cells.eq(3);
var fp = cells.eq(6);
// Get current cell values as a number
var nt = Number(cells.eq(1).text());
var nh = Number(cells.eq(2).text());
var f = Number(cells.eq(5).text());
// Update totals
tp.text(nh + i - nt);
fp.text(nh + i - f);
});
Side note: The value of var i = $(this).val(); could be null but not sure how you want to handle this - possibly just use
var i = $(this).val();
if (!i) {
return; // don't do any calculations
}
You need to know the difference between val(), text() and html()
val() is for getting and setting values for form elements, input, select etc.
text() is for getting and setting plain unformatted text for non form elements.
html() is for getting and setting inner Html from a node
So what you want is:
$tp.text($nh.text() + $i.val() - $nt.text());
$fp.text($nh.text() + $i.val() - $f.text());
Also be careful as + is both mathematical addition and string concatenation in javascript so you may want to cast your parse the strings to the appropriate number type.
in my shopping cart my code produces a structure like below every time based on user's choice. every tr is for a product and x indicates different value based on product and id is the id of product.So x,id and number of trs every time differ.
<tr>
<td><span class="product-id" value="x"></span></td>
<td><img class="product-img" value="x" /></td>
<td><a class="product-name" value="x"></a></td>
<td><span class=product-color value="x"></span>
<td><select class="qnty-id" value="x"></select></td>
<td><span class="price-id" value="x"></span></td>
<td><span class="total-id" value="x"></span></td>
</tr>
I want to collect them in an array or Json format like this:
array(x => array(
'id'=>'product-id',
'name'=>'product-name',
'color'=>'product-color',
'quntity'=>'qnty-x',
'price'=>'price-x',
'total'=>'total-x')
)
And send them to my server side using Ajax.
I'd appreciate any help.
Considering your table id as table, try this:
var table = $('#table');
var elems = table.find('tr');
var cartArray = [];
elems.each(function (i, item) {
var itemSelector = $(item);
var id = itemSelector.find('.product-id').attr('value');
var img = itemSelector.find('.product-img').attr('value');
var name = itemSelector.find('.product-name').attr('value');
var color = itemSelector.find('.product-color').attr('value');
var quantity = itemSelector.find('.qnty-id').val();
var price = itemSelector.find('.price-id').text();
var total = itemSelector.find('.total-id').text();
cartArray.push({id: id, img: img, name: name, color: color, quantity: quantity, price: price, total: total});
});
console.log(cartArray);
I'm not sure what to do in order to complete this project. I need to create a shopping cart that uses only one HTML page. I have the table set up showing what is being sold but where I am lost is the JavaScript.
I don't know how to link the "Add to Cart" button with all the necessary data( The name, description, and price) to be able to add it to the cart. I don't need to be able to remove it from the cart, but it does need to show the total. After searching online for a few answers, I've tried some things but just cannot figure it out.
Any help is definitely appreciated because I am completely lost at this point and am new to JavaScript in general.
This is the jsFiddle but that was a little confusing to me, because it's working differently on there than if I just went to Run in Notepad++
jsFiddle: http://jsfiddle.net/renavi/ATjvt/5/
function AddtoCart() {
console.log('hi');
var x = document.getElementById('Items');
var new_row = x.rows[1].cloneNode(true);
var len = x.rows.length;
new_row.cells[0].innerHTML = len;
var inp1 = new_row.cells[1].getElementsByTagName('input')[0];
inp1.id += len;
inp1.value = '';
var inp2 = new_row.cells[2].getElementsByTagName('input')[0];
inp2.id += len;
inp2.value = '';
x.appendChild(new_row);
}
The direct file is here
Pastebin: http://pastebin.com/sutGWjSY
You simply need to use simpleCart
It is a free and open-source javascript shopping cart that easily integrates with your current website.
You will get the full source code at github
For a project this size, you should stop writing pure JavaScript and turn to some of the libraries available. I'd recommend jQuery (http://jquery.com/), which allows you to select elements by css-selectors, which I recon should speed up your development quite a bit.
Example of your code then becomes;
function AddtoCart() {
var len = $("#Items tr").length, $row, $inp1, $inp2, $cells;
$row = $("#Items td:first").clone(true);
$cells = $row.find("td");
$cells.get(0).html( len );
$inp1 = $cells.get(1).find("input:first");
$inp1.attr("id", $inp1.attr("id") + len).val("");
$inp2 = $cells.get(2).find("input:first");
$inp2.attr("id", $inp2.attr("id") + len).val("");
$("#Items").append($row);
}
I can see that you might not understand that code yet, but take a look at jQuery, it's easy to learn and will make this development way faster.
I would use the libraries already created specifically for js shopping carts if I were you though.
To your problem; If i look at your jsFiddle, it doesn't even seem like you have defined a table with the id Items? Maybe that's why it doesn't work?
I think it is a better idea to start working with a raw data and then translate it to DOM (document object model)
I would suggest you to work with array of objects and then output it to the DOM in order to accomplish your task.
You can see working example of following code at http://www.softxml.com/stackoverflow/shoppingCart.htm
You can try following approach:
//create array that will hold all ordered products
var shoppingCart = [];
//this function manipulates DOM and displays content of our shopping cart
function displayShoppingCart(){
var orderedProductsTblBody=document.getElementById("orderedProductsTblBody");
//ensure we delete all previously added rows from ordered products table
while(orderedProductsTblBody.rows.length>0) {
orderedProductsTblBody.deleteRow(0);
}
//variable to hold total price of shopping cart
var cart_total_price=0;
//iterate over array of objects
for(var product in shoppingCart){
//add new row
var row=orderedProductsTblBody.insertRow();
//create three cells for product properties
var cellName = row.insertCell(0);
var cellDescription = row.insertCell(1);
var cellPrice = row.insertCell(2);
cellPrice.align="right";
//fill cells with values from current product object of our array
cellName.innerHTML = shoppingCart[product].Name;
cellDescription.innerHTML = shoppingCart[product].Description;
cellPrice.innerHTML = shoppingCart[product].Price;
cart_total_price+=shoppingCart[product].Price;
}
//fill total cost of our shopping cart
document.getElementById("cart_total").innerHTML=cart_total_price;
}
function AddtoCart(name,description,price){
//Below we create JavaScript Object that will hold three properties you have mentioned: Name,Description and Price
var singleProduct = {};
//Fill the product object with data
singleProduct.Name=name;
singleProduct.Description=description;
singleProduct.Price=price;
//Add newly created product to our shopping cart
shoppingCart.push(singleProduct);
//call display function to show on screen
displayShoppingCart();
}
//Add some products to our shopping cart via code or you can create a button with onclick event
//AddtoCart("Table","Big red table",50);
//AddtoCart("Door","Big yellow door",150);
//AddtoCart("Car","Ferrari S23",150000);
<table cellpadding="4" cellspacing="4" border="1">
<tr>
<td valign="top">
<table cellpadding="4" cellspacing="4" border="0">
<thead>
<tr>
<td colspan="2">
Products for sale
</td>
</tr>
</thead>
<tbody>
<tr>
<td>
Table
</td>
<td>
<input type="button" value="Add to cart" onclick="AddtoCart('Table','Big red table',50)"/>
</td>
</tr>
<tr>
<td>
Door
</td>
<td>
<input type="button" value="Add to cart" onclick="AddtoCart('Door','Yellow Door',150)"/>
</td>
</tr>
<tr>
<td>
Car
</td>
<td>
<input type="button" value="Add to cart" onclick="AddtoCart('Ferrari','Ferrari S234',150000)"/>
</td>
</tr>
</tbody>
</table>
</td>
<td valign="top">
<table cellpadding="4" cellspacing="4" border="1" id="orderedProductsTbl">
<thead>
<tr>
<td>
Name
</td>
<td>
Description
</td>
<td>
Price
</td>
</tr>
</thead>
<tbody id="orderedProductsTblBody">
</tbody>
<tfoot>
<tr>
<td colspan="3" align="right" id="cart_total">
</td>
</tr>
</tfoot>
</table>
</td>
</tr>
</table>
Please have a look at following free client-side shopping cart:
SoftEcart(js) is a Responsive, Handlebars & JSON based, E-Commerce shopping cart written in JavaScript with built-in PayPal integration.
Documentation
http://www.softxml.com/softecartjs-demo/documentation/SoftecartJS_free.html
Hope you will find it useful.
Here's a one page cart written in Javascript with localStorage. Here's a full working pen. Previously found on Codebox
cart.js
var cart = {
// (A) PROPERTIES
hPdt : null, // HTML products list
hItems : null, // HTML current cart
items : {}, // Current items in cart
// (B) LOCALSTORAGE CART
// (B1) SAVE CURRENT CART INTO LOCALSTORAGE
save : function () {
localStorage.setItem("cart", JSON.stringify(cart.items));
},
// (B2) LOAD CART FROM LOCALSTORAGE
load : function () {
cart.items = localStorage.getItem("cart");
if (cart.items == null) { cart.items = {}; }
else { cart.items = JSON.parse(cart.items); }
},
// (B3) EMPTY ENTIRE CART
nuke : function () {
if (confirm("Empty cart?")) {
cart.items = {};
localStorage.removeItem("cart");
cart.list();
}
},
// (C) INITIALIZE
init : function () {
// (C1) GET HTML ELEMENTS
cart.hPdt = document.getElementById("cart-products");
cart.hItems = document.getElementById("cart-items");
// (C2) DRAW PRODUCTS LIST
cart.hPdt.innerHTML = "";
let p, item, part;
for (let id in products) {
// WRAPPER
p = products[id];
item = document.createElement("div");
item.className = "p-item";
cart.hPdt.appendChild(item);
// PRODUCT IMAGE
part = document.createElement("img");
part.src = "images/" +p.img;
part.className = "p-img";
item.appendChild(part);
// PRODUCT NAME
part = document.createElement("div");
part.innerHTML = p.name;
part.className = "p-name";
item.appendChild(part);
// PRODUCT DESCRIPTION
part = document.createElement("div");
part.innerHTML = p.desc;
part.className = "p-desc";
item.appendChild(part);
// PRODUCT PRICE
part = document.createElement("div");
part.innerHTML = "$" + p.price;
part.className = "p-price";
item.appendChild(part);
// ADD TO CART
part = document.createElement("input");
part.type = "button";
part.value = "Add to Cart";
part.className = "cart p-add";
part.onclick = cart.add;
part.dataset.id = id;
item.appendChild(part);
}
// (C3) LOAD CART FROM PREVIOUS SESSION
cart.load();
// (C4) LIST CURRENT CART ITEMS
cart.list();
},
// (D) LIST CURRENT CART ITEMS (IN HTML)
list : function () {
// (D1) RESET
cart.hItems.innerHTML = "";
let item, part, pdt;
let empty = true;
for (let key in cart.items) {
if(cart.items.hasOwnProperty(key)) { empty = false; break; }
}
// (D2) CART IS EMPTY
if (empty) {
item = document.createElement("div");
item.innerHTML = "Cart is empty";
cart.hItems.appendChild(item);
}
// (D3) CART IS NOT EMPTY - LIST ITEMS
else {
let p, total = 0, subtotal = 0;
for (let id in cart.items) {
// ITEM
p = products[id];
item = document.createElement("div");
item.className = "c-item";
cart.hItems.appendChild(item);
// NAME
part = document.createElement("div");
part.innerHTML = p.name;
part.className = "c-name";
item.appendChild(part);
// REMOVE
part = document.createElement("input");
part.type = "button";
part.value = "X";
part.dataset.id = id;
part.className = "c-del cart";
part.addEventListener("click", cart.remove);
item.appendChild(part);
// QUANTITY
part = document.createElement("input");
part.type = "number";
part.value = cart.items[id];
part.dataset.id = id;
part.className = "c-qty";
part.addEventListener("change", cart.change);
item.appendChild(part);
// SUBTOTAL
subtotal = cart.items[id] * p.price;
total += subtotal;
}
// EMPTY BUTTONS
item = document.createElement("input");
item.type = "button";
item.value = "Empty";
item.addEventListener("click", cart.nuke);
item.className = "c-empty cart";
cart.hItems.appendChild(item);
// CHECKOUT BUTTONS
item = document.createElement("input");
item.type = "button";
item.value = "Checkout - " + "$" + total;
item.addEventListener("click", cart.checkout);
item.className = "c-checkout cart";
cart.hItems.appendChild(item);
}
},
// (E) ADD ITEM INTO CART
add : function () {
if (cart.items[this.dataset.id] == undefined) {
cart.items[this.dataset.id] = 1;
} else {
cart.items[this.dataset.id]++;
}
cart.save();
cart.list();
},
// (F) CHANGE QUANTITY
change : function () {
if (this.value == 0) {
delete cart.items[this.dataset.id];
} else {
cart.items[this.dataset.id] = this.value;
}
cart.save();
cart.list();
},
// (G) REMOVE ITEM FROM CART
remove : function () {
delete cart.items[this.dataset.id];
cart.save();
cart.list();
},
// (H) CHECKOUT
checkout : function () {
// SEND DATA TO SERVER
// CHECKS
// SEND AN EMAIL
// RECORD TO DATABASE
// PAYMENT
// WHATEVER IS REQUIRED
alert("TO DO");
/*
var data = new FormData();
data.append('cart', JSON.stringify(cart.items));
data.append('products', JSON.stringify(products));
var xhr = new XMLHttpRequest();
xhr.open("POST", "SERVER-SCRIPT");
xhr.onload = function(){ ... };
xhr.send(data);
*/
}
};
window.addEventListener("DOMContentLoaded", cart.init);