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);
Related
enter image description hereI am working on a Shopping Cart problem and I have a table in HTML to input various objects in an Array. I want to create a "edit" button to display the specific array info back on the table.
I am working on just Visual Studio Code and Javascript. No other tools used as this is the fundamentals for my course.
So what should I code in editAdminFunc to display the objects in HTML?
Please see my code for info.
// create a flower array
var flowerArray=[];
// declare a member object
function flower(id, name, desc, price, stock, image){
this.id = id; //id
this.name = name; //name
this.desc= desc; //description
this.price = price; //price
this.stock = stock; //quantity
this.image = image; //image
}
function addFlower(){
alert("addFlower function is being triggered!");
var newFlower = new flower(
document.getElementById("memId").value,
document.getElementById("memName").value,
document.getElementById("memDesc").value,
document.getElementById("memPrice").value,
document.getElementById("memStock").value,
document.getElementById("memImage").src,
);
flowerArray.push(newFlower);
console.log(flowerArray);
}
//this function is to show the flowers in list format (for admin view)
function listFlowerFunc(){
alert("listFlowerFunc is being triggered!");
var displayText = "<table border=1, align = center>";
displayText += "<tr><th>Product ID</th><th>Name</th><th>Description</th><th>Unit Price</th><th>Stock</th><th>Image</th><th>Actions</th></tr>";
for (var i=0; i<flowerArray.length; i++){
displayText = displayText + "<tr><td>"+flowerArray[i].id+"</td><td>"+flowerArray[i].name+"</td><td>"+flowerArray[i].desc+"</td><td>"+flowerArray[i].price+"</td><td>"+flowerArray[i].stock+"</td><td>"+flowerArray[i].src+"</td><td><button onclick =editAdminFunc()>edit</button><button onclick =deleteAdminFunc()>delete</button></td></tr>"
}
displayText = displayText+"</table>";
document.getElementById("productlist").innerHTML = displayText;
}
//editAdminFunc
function editAdminFunc(i){
alert("editAdminFunc() has been triggered!")
document.getElementById("memId").value = ""; //to display array objects in the form
document.getElementById("memName").value = "";
document.getElementById("memDesc").value= "";
document.getElementById("memPrice").value= "";
document.getElementById("memStock").value= "";
document.getElementById("memImage").src= "";
}
<div id="admin" align="center">
<p>
<button onclick='showProductForm()'>Add Products</button> | <button id ="flowerListId" onclick="listFlowerFunc()">List Products</button>
</p>
<div id="productlist">
</div>
<br>
<div id="productForm" align="center">
<table id = "prodTable" border ="1">
<tr><td align="right">Product ID:</td><td><input type="text" id="memId" size="35"/></td></tr>
<tr><td align="right">Name:</td><td><input type="text" id="memName" size="35"/></td></tr>
<tr><td align="right">Description:</td><td><input type="text" id="memDesc" size="35"/></td></tr>
<tr><td align="right">Unit Price($):</td><td><input type="text" id="memPrice" size="35"/></td></tr>
<tr><td align="right">Stock:</td><td><input type="text" id="memStock" size="35"/></td></tr>
<tr><td align="right">Image:</td><td><input type="file" id="memImage"/></td></tr>
<tr><td> </td>
<td><button id="clearFormBtn" onclick="clearFormFunc()">Clear</button>
<button id="addProdBtn" onclick="addFlower()">Add</button>
<button id="updateProdBtn" onclick="editHtmlTableSelected()">Update</button>
</td></tr>
</table>
</div>
</div>
the right way to create an element in javascript, would be something like that
<div class="some"></div>
function addElement () {
// create new "p" element
var newP = document.createElement("p");
// add content -- the data you want display
var newContent = document.createTextNode("hello, how are you?");
newP.appendChild(newContent); //add content inside the element.
// add the element and content to DOM
var currentDiv = document.getElementById("some");
document.body.insertBefore(newP, currentDiv);
}
addElement();
https://developer.mozilla.org/es/docs/Web/API/Document/createElement
Now, if we adapt that information to the context of the tables, we can do it on this way to generate the data dynamically
arr = [
'item 1',
'item 2',
'item 3',
'item 4',
'item 5'
];
function addElement () {
arr.forEach(function(el,index,array){
let tableRef = document.getElementById('some');
// Insert a row at the end of the table
let newRow = tableRef.insertRow(-1);
// Insert a cell in the row at index 0
let newCell = newRow.insertCell(0);
// Append a text node to the cell
let newText = document.createTextNode(el);
newCell.appendChild(newText);
});
}
addElement();
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableRowElement/insertCell
link to demo: Fiddle
I have the following JSON structure:
[
{"key":1,"idProduct":"Monitor","obsProduct":""},
{"key":2,"idProduct":"Mouse","obsProduct":""},
{"key":3,"idProduct":"Keyboard","obsProduct":""},
{"key":4,"idProduct":"Processor","obsProduct":""}
]
And the following HTML table (representing the JSON):
When user click on "Remove" button, I need to remove the corresponding iten on JSON. When user click, I can capture the key, so I need to remove iten using the key value.
Assuming that the user click on "Remove" button on "Mouse", so, the JSON needs to return that way:
[
{"key":1,"idProduct":"Monitor","obsProduct":""},
{"key":3,"idProduct":"Keyboard","obsProduct":""},
{"key":4,"idProduct":"Processor","obsProduct":""}
]
How can I do this?
HTML of table:
<div class="row">
<div class="col-md-12">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="table-products">
<thead style="background-color: #f2f2f2">
<tr class="text-center">
<th style="width: 40%">Product</th>
<th style="width: 40%">Obs</th>
<th style="width: 20%">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="3">No iten!</td>
</tr>
<!-- Will be generated! -->
</tbody>
</table>
</div>
</div>
</div>
JS that generates the lines:
var i = 1;
var itensArray = [];
var nameProduct = $("input[name='nameProd']").val();
var obsProduct = $("input[name='obsProd']").val();
if(i <= 5)
{
var newItem = '<tr class="itemRow"><td>' + nameProduct + '</td><td>' + obsProduct + '</td><td><button type="button" name="' + i + '" class="btn btn-outline-danger btn-sm" id="btnRemoveProduct"><i class="far fa-trash-alt"></i> Remove</button></td></tr>';
if(i == 1)
$("#table-products tbody").html(newItem);
else
$("#table-products tbody").append(newItem);
var products = {
key: i,
idProduct: nameProduct,
obsProduct: obsProduct
};
itensArray.push(products)
var aux = JSON.stringify(itensArray);
i++;
console.log(aux);
}
JS that remove lines from table:
$("#table-products").on('click', '#btnRemoveItem', function(){
var idProduct = $(this).attr("name");
$(this).closest('tr').remove();
toastr.success('Iten removed!');
i--;
if(i == 1)
{
var defaultItem = '<tr><td colspan="3">No iten added!</td></tr>';
$("#table-products tbody").html(defaultItem);
}
/* I NEED TO PUT HERE THE CODE TO REMOVE ITEM FROM JSON */
});
Iterating through the array of objects and finding the matching object having key as the key value which is captured when clicking on remove button.
var itensArray = [
{"key":1,"idProduct":"Monitor","obsProduct":""},
{"key":2,"idProduct":"Mouse","obsProduct":""},
{"key":3,"idProduct":"Keyboard","obsProduct":""},
{"key":4,"idProduct":"Processor","obsProduct":""}
];
//key is captured in a variable on click of remove button.
var idProduct = 2;
for (var i = 0; i < itensArray.length; i++) {
var obj = itensArray[i];
if (obj.key === idProduct) {
itensArray.splice(i, 1);
}
}
console.log(itensArray);
The simplest way is to assing some id to button which responds entry id. While delete button is clicked you can extract ID from button and you know which row to delete.
You said you can capture the key, so I'm assuming you've got some kind of click handler function that's receiving that key. From there the best way to do it is probably to create a new array that filters out the element that matches, and replace the old array with the new. (Generally considered a better practice than mutating the array in place with something like .splice)
const capturedKey = event.target.value // or however you're capturing it
yourArray = yourArray.filter(obj => obj.key !== capturedKey)
You can find the index using Array.findIndex (It will return on the first match so it is an optimized way if your 'key' values are unique)
const myArray = [
{"key":1,"idProduct":"Monitor","obsProduct":""},
{"key":2,"idProduct":"Mouse","obsProduct":""},
{"key":3,"idProduct":"Keyboard","obsProduct":""},
{"key":4,"idProduct":"Processor","obsProduct":""}
];
const idToDelete = 2; // retrieved via clicked btn
const idx = myArray.findIndex( item => item.key == idToDelete );
if(idx != -1) {
myArray.splice(idx, 1);
}
console.log(myArray)
I'am trying to create a table with a 100 rows but I dont want to use push because then the page gets rendered for each push. The table should be empty at first but when I click a button the table will create all the rows.
The problem here is that I dont se the rows when I click the button. But I can only set self.row = ko.observableArray() once?
JS
RowModel = function(numbers) {
var self = this;
self.numbers = numbers;
}
TableViewModel = function() {
var self = this;
self.rows = null;
self.createRows = function() {
var arr = [];
var numbers = [];
for(var i=0; i < 100; i++){
for(var p=0; p < 4; p++){
numbers[p] = p;
}
arr[i] = new RowModel(numbers);
}
self.rows = ko.observableArray(arr);
}
};
ko.applyBindings(new TableViewModel());
HTML
<button data-bind="click: createRows">Create</button>
<table>
<tbody data-bind="foreach: rows">
<tr>
<td data-bind="text: numbers[0]"></td
<td data-bind="text: numbers[1]"></td>
<td data-bind="text: numbers[2]"></td>
<td data-bind="text: numbers[3]"></td>
</tr>
</tbody>
</table>
Always create the observable up front, and set the data using a function call with the data e.g.
self.rows = ko.observable([]);
Then set the data (not as a push for each, as you correctly said) using:
self.rows(arr);
The full code is here in this fiddle:https://jsfiddle.net/brianlmerritt/y0x0wwy5/
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>
I have a bit of a problem. I'm trying to add,remove and edit items in an array of objects, showing its content in a html table,but without form submission. So far I've managed to add items ( thanks to David Calhoun ), but now I facing a new issue, since I don't know how to get the row index (when I click the delete image) ,so that I can delete that row. Is there any way to achieve this?
here's my code
<script>
var table = [];
function addDetail()
{
table.push({
price: document.getElementById('price').value,
description: document.getElementById('descripcion').value
});
showRow(table.length-1);
resetEntries();
}
function resetEntries()
{
document.getElementById('price').value='';
document.getElementById('descripcion').value='';
document.getElementById('price').focus();
}
function showRow(i)
{
if (table.length>0){
var tbl = document.getElementById('tabla_estilo');
var newRow = tbl.insertRow(tbl.rows.length);
var cell1 = newRow.insertCell(0);
cell1.textAlign='center';
cell1.innerHTML='<img src="images/edit.png" width="14" height="14" alt="Edit"/>'
var cell2 = newRow.insertCell(1);
cell2.textAlign='center';
cell2.innerHTML='<img src="images/delete.png" width="14" height="14" alt="Delete"/>'
var cell3 = newRow.insertCell(2);
cell3.textAlign='center';
cell3.innerHTML=table[i].price;
var cell4 = newRow.insertCell(3);
cell4.textAlign='center';
cell4.innerHTML=table[i].description;
}
}
And here's how my form looks
From the onclick handler for the delete button, you can traverse up to its <tr> and then get that row's rowIndex property.
So in the onclick:
var node = this.parentNode;
while( node && node.tagName !== 'TR' ) {
node = node.parentNode;
}
var index = node.rowIndex;
So when you're setting up your row cells, you can add a handler:
var cell2 = newRow.insertCell(1);
cell2.textAlign='center';
cell2.innerHTML='<img src="images/delete.png" width="14" height="14" alt="Delete"/>'
cell2.firstChild.onclick = function() {
var node = this.parentNode;
while( node && node.tagName !== 'TR' ) {
node = node.parentNode;
}
var index = node.rowIndex;
alert('index');
return false;
}
This creates a new function for each row. It would be better to reference a named function instead.
with JQuery use any of these selector
$('table tr').each(function(i, v) { alert((i+1) + ' row') });
$('table tr:nth-child(i)').hide();
OR
<a href="#" class="delete" onclick="$(this).parent().parent().hide()">
When you create a new row in the table use a custom attribute in to store the index of the element in the array:
<tr position='0'><td></td><td></t></tr>
<tr position='1'><td></td><td></t></tr>
<tr position='2'><td></td><td></t></tr>
<tr position='3'><td></td><td></t></tr>
Alternatively, if your rows are always in the same order as the elements in the array you may check how many previous siblings there are before this row.
I would use the first approach as it will still work if you reorder the rows in the table.
Make sure that if you delete the row you then recalculate row position attributes.