Creating Html table from array (Using prompt) - javascript

I am new to Html. This is my first html javascript program and I have an issue with it.
A user puts his/her gpa CS102 A 3, Math101 B 3. Then, I put the data into an Array. The problem is when I create the table. I want to create a table like
THL100 B+ 3
PHL107 A 3
ENG120 C+ 3
MTH245 A 4
CSC221 A 3
What kind of loop I should use? I tried to use a for loop but it just doesn't work.
Here is my code:
function load(){
var data = [];
while(true) {
line = prompt("Enter course name, grade, and credit hours or click OK with no data to terminate");
if(line == null || line == "") {
break;
}
var values = line.split(/\s/);
var citem = values[0];
data.push(citem);
var gpa = parseFloat(values[1]);
var cgpa = [gpa];
data.push(cgpa);
var unit = values[2];
var cunit = [unit];
data.push(cunit);
}
return data;
}
function display(data) {
var table=document.getElementById('result');
table.innerHTML= "<tr><th> COURSE </th><th> GRADE </th><th> HOURS </th></tr>";
for(var i in data){
table.innerHTML +="<tr><td>" + data[i] + "</td><td>" + data[i]+1 + "</td><td>" + data[i]+2 + "</td></tr>";
}
}
data = load();
display(data);
<table id="result" border="1px" class="classy">
</table>
<span id="text"></span>

the problem is with accessing data not the loop, store each line as one element in the array, like object will be easy:
function load(){
var data = [];
while(true) {
line = prompt("Enter course name, grade, and credit hours or click OK with no data to terminate");
if(line == null || line == "") {
break;
}
var values = line.split(/\s/);
var line = {
COURSE: values[0],
GRADE: parseFloat(values[1]),
HOURS: values[2]
};
data.push(line); // now your array is [{COURSE: value, GRADE: value, HOURS: value}, {}, ...]
}
return data;
}
function display(data) {
var table=document.getElementById('result');
table.innerHTML= "<tr><th> COURSE </th><th> GRADE </th><th> HOURS </th> </tr>";
for(var i in data){
table.innerHTML +="<tr><td>" + data[i]["COURSE"] + "</td><td>" + data[i]["GRADE"] + "</td> <td>" + data[i]["HOURS"] + "</td></tr>";
}
}
UPDATE: yes the data is accessible inside the loop but for any variable
function display(data) {
var table = document.getElementById('result');
table.innerHTML = "<tr><th> COURSE </th><th> GRADE </th><th> HOURS </th> </tr>";
let totalgp = 0; // if the total is for all courses define it here
for (var i in data) {
let totalgp = 0; // if total grade for each course separately define it inside the loop
if (data[i]["GRADE"] == "A") {
var gp = 4 * data[i]["HOURS"];
totalgp = totalgp + gp;
}
table.innerHTML += "<tr><td>" + data[i]["COURSE"] + "</td><td>" + data[i]["GRADE"] + "</td> <td>" + data[i]["HOURS"] + "</td></tr>";
}
}

The data should be stored in a 2-dimensional array to easily access the elements. The usage of for loop is right.
To append the first row -
table.innerHTML +="<tr><td>" + data[0][0] + "</td><td>" + data[0][1] + "</td> <td>" + data[0][2] + "</td></tr>";
similarly for 2nd row,
table.innerHTML +="<tr><td>" + data[1][0] + "</td><td>" + data[1][1] + "</td> <td>" + data[1][2] + "</td></tr>";

Related

Calling the function on every iteration of for loop in Javascript

function myFunction(xml) {
var i;
var xmlDoc = xml.responseXML;
var table =
"<tr><th>Title</th><th>Author</th><th>Cover Page</th><th>Ratings</th></tr>";
var x = xmlDoc.getElementsByTagName("best_book");
for (i = 0; i < x.length; i++) {
bookname = x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue;
authorname = x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
table +=
"<tr><td class='book'>" +
bookname +
"</td><td class='author'>" +
authorname +
"</td><td>" +
"<img src='" +
x[i].getElementsByTagName("image_url")[0].childNodes[0].nodeValue +
"' height='100px' width='70px'>" +
"</td><td>" +
"<div class='stars' data-rating='1'>" +
"<span class='star'> </span>" +
"<span class='star'> </span>" +
"<span class='star'> </span>" +
"<span class='star'> </span>" +
"<span class='star'> </span>" +
"<input type='button' value='Add Rating' onClick = 'submitRating()'>" +
"</div>" +
"</td></tr>";
console.log(bookname);
}
document.getElementById("result").innerHTML = table;
}
async function submitRating() {
try {
let boo = bookname;
console.log(boo);
let auth = authorname;
console.log(auth);
let rat = 5;
console.log(rat);
let data = JSON.stringify({
author: auth,
book: boo,
rating: rat
});
console.log(data);
let res = await fetch(hostUrl + "api/ratings", {
method: "POST",
body: data,
headers: {
"Content-Type": "application/json"
}
});
console.log(res);
res.json().then(matter => {
console.log(matter);
});
// let myJson = res.json();
// console.log(myJson);
if (res.status == 200) {
console.log("the status is " + res.status);
} else {
console.log("the status is " + res.status);
alert("rating not given");
}
} catch (error) {
console.log("Error:" + error);
}
}
I am trying to call submitRating function on every iteration of for loop,
but I am not getting the correct method for this in JavaScript.
Right now, after running the loop, onclick = submitRating() function only submitting the last value in mongodb.
Can someone help me with this please?
That is because the bookname and authorname retain the last value set by the final iteration of the for loop. In other words, these variables are simply overwritten multiple times until the for loop ends. If you want to store these information on a per-item basis, you can store them in HTML5 data- attributes and retrieve them in the onclick handler.
For example, you can do this:
"<input type='button' value='Add Rating' data-bookname='"+bookname+"' data-authorname='"+authorname+"' onClick='submitRating(this)' />"
And then, in your submitRating method, you can simply read the information using Element.dataset:
async function submitRating(el) {
const bookname = el.dataset.bookname;
const authorname = el.dataset.authorname;
// More logic here
}

Jquery .each not working for first row from the table

I am using jquery .each to loop the values and push in JSON. it is working for all the rows leaving the first row.
for (j = 0; j < parsedResult.length; j++) {
var pack_id = parsedResult[j].pack_id;
var pack_dsc = parsedResult[j].pack_dsc;
var pack_base_amount = parsedResult[j].pack_base_prc;
var pack_tax_amount = parsedResult[j].pack_tax_amt;
var pack_grand_total = parsedResult[j].pack_grand_total;
row += "<span id='single_pack_details'><span id='pack_id' class='hidden'>" + pack_id + "</span><b>Pack description: </b><span id='pack_dsc'>" + pack_dsc + "</span><b>Pack Amount:</b> ₹ <span id='pack_grand_total'>" + pack_grand_total + "</span></div><span class='hidden' id='pack_base_amount'>" + pack_base_amount + "</span><span class='hidden' id='pack_tax_amount'>" + pack_tax_amount + "</span></span>";
}
Below is where i trying to put it in a loop and pushing to pack_details object
$(this).closest("tr").find('#single_pack_details').each(function () {
var obj = {
pack_id: $(this).closest("span").find("#pack_id").text(),
pack_dsc: $(this).closest("span").find("#pack_dsc").text(),
pack_grand_total: $(this).closest("span").find("#pack_grand_total").text(),
pack_base_amount: $(this).closest("span").find("#pack_base_amount").text(),
pack_tax_amount: $(this).closest("span").find("#pack_tax_amount").text()
}
pack_details.push(obj);

Updating then displaying a variable during jQuery .submit function

On page load I am setting:
var qty = 1;
Then, within the page, the user chooses a product & selects a quantity which is captured as the variable clicks.
I wish to then click a button#addToInventory which will update the qty variable & display it in the console. I am attempting this as follows:
$("#addToInventory").submit(function(event){qty = clicks;console.log(" QTY: " + qty );})
This does not work (the console displaying a qty of 1 regardless of the set value, however immediately after clicking the button, if I then manually type console.log(" QTY: " + qty ) I see the correct qty as set in the console.
I have tried to delay the console.log as follows, but this does not work either:
$("#addToInventory").submit(function(event){qty = clicks;setTimeout(function (){console.log( " QTY: " + qty );}, 1000);})
--EDIT--
The above is a simplified sample of the production code which is as follows:
$.ajax(settings).done(function(response) {
var output = "";
for (i in response.Products) {
var productID = response.Products[i].ProductId;
var name = response.Products[i].Name;
var imagePath = response.Products[i].ImagePath;
var EAN = response.Products[i].EANBarcode;
var price = response.Products[i].PriceDescription;
var offer = response.Products[i].OfferPromotion;
var offerValid = response.Products[i].OfferValidity;
var qty = 0;
output += "<div class='uk-width-medium-1-4'> <div class='md-card'> <div class='md-card-head uk-text-center uk-position-relative'> <div class='uk-badge uk-badge-danger uk-position-absolute uk-position-top-left uk-margin-left uk-margin-top'>" + price + "</div><img class='md-card-head-img' src='" + imagePath + "'/> </div><div class='md-card-content'> <h4 class='heading_c uk-margin-bottom'>" + name + "<span class='sub-heading'>SKU: " + EAN + "</span></h4> <p>" + offer + "</p><p><i>" + offerValid + "</i></p><div align='center'><button data-uk-modal=\"{target:'#modal_" + productID + "'}\" class=\"md-btn md-btn-flat md-btn-flat-primary\" >ADD TO INVENTORY</button><div class=\"uk-modal\" id=\"modal_" + productID + "\"> <div class=\"uk-modal-dialog\"> <div class='uk-modal-header'> <h3 class='uk-modal-title md-card-toolbar-heading-text'><i class='md-icon material-icons'></i> QTY To Add</h3> </div><p class='uk-text-left'>How many <i><b>" + name + "</b></i> do you want to add to your home inventory : <br></p><div class='uk-text-center'> <form id='addToInventory_" + productID + "'> </p><br><h2> <table class='uk-table uk-table-popup uk-table-hover-popup'> <tbody> <td class='uk-text-center' type='button' onClick='clicks_" + productID + "--;updateClickCount_" + productID + "();' id='push-'><i class='md-icon material-icons'></i></td><td class='uk-text-center' id='clickCount_" + productID + "'>1</td><td class='uk-text-center' type='button' onClick='clicks_" + productID + "++;updateClickCount_" + productID + "();' id='push+'><i class='md-icon material-icons'></i></td></tbody> </table> </h2> <br></p><button id='addToInventory_" + productID + "-submit' type='submit' class='md-btn md-btn-flat md-btn-flat-primary'>ADD TO INVENTORY</button></form><scr" + "ipt type=\"application/javascript\">var clicks_" + productID + " = 1;var minimum = 1;function updateClickCount_" + productID + "() {if (clicks >= minimum) {document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";} else {clicks_" + productID + " = 1;document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";}} $(\"#addToInventory_" + productID + "\").submit(function(event){qty = 0;console.log('QTY IS: '+qty+' CLICKS Are: '+clicks_"+productID+");qty = clicks_"+productID+";setTimeout(function (){console.log(\""+ name + " QTY: " + qty +"\");}, 1000);}) </scr" + "ipt></div></div></div></div></div></div></div>";
}
$("#allResults").html(output);
$("#searchTerm").html(searchTerm);
});
});
Your qty will always be one because you are creating the variable and assigning it to be 0 inside of the for loop. Every time it runs the for loop a new qty var is created an set to 0 then it is given the 1 value for the iteration variable (i). So the fact that qty is being instantiated in the loop it will never increase.
If you move the qty variable out of the for loop it should work.
var qty = 0;
For (.............) {
// your code here
}

Creating an array object within an array object

I have an array object that needs another array object added to it. So i have details of the object that need the rows in a table to be added to that object as an array. I have tried a few suggestions on stackoverflow , but none seems to be working, and i am not sure this has something to do with the fact that the table is created by js.
// Adding Cosignment number
$('#parcel-overview').append(
// Add main tables which will display the added packages
'<table border="1">' +
'<thead><tr><th>Packages</th><th>Weight</th> <th>Vol Weight</th><th>Charge Weight</th> <th>Price</th></tr></thead><tbody id="parcels-added-overview"></tbody> ' +
'</table>'
);
for (var i = 0; i < packageNum; i++) {
var ii = (i + 1).toString();
// Working out volemetric weight
wei = $('#added-parcels #weighting-' + ii + ' input').val();
len = $('#added-parcels #lengthing-' + ii + ' input').val();
wid = $('#added-parcels #widthing-' + ii + ' input').val();
hei = $('#added-parcels #heighting-' + ii + ' input').val();
//Calculating Volumetric weight
tot = ((len * wid * hei) / 5000).toFixed(1);
pri = (tot * 23).toFixed(2);
chr = (tot * 12).toFixed(2);
$('#parcels-added-overview').append(
'<tr>' +
'<td class="par-id">' + (i + 1).toString() + '</td>' +
'<td class="par-weight">' + wei.toString() + ' kg\'s</td>' +
'<td class="par-vol-weight">' + tot.toString() + ' kg\'s</td>' +
'<td class="par-charge-weight">R ' + chr.toString() + '</td>' +
'<td class="par-price">R ' + pri.toString() + ' </td>' +
'</tr>'
);
}
I then want to add the values of that table that have been added dynamically to an object array that is then added to the primary object array.
var parcelObj = new Object();
$.each($('#parcels-added-overview tr'),function (index) {
parcelObj.parcelId = $(this).children('.par-id').text();
parcelObj.totalWeight = $(this).children('.par-weight').text();
parcelObj.volWeight = $(this).children('.par-vol-weight').text();
parcelObj.chargeWeight = $(this).children('.par-charge-weight').text();
parcelObj.overallPrice = $(this).children('.par-price').text();
parcelsArr.push(parcelObj);
});
consignmentObj.parcels = parcelsArr;
consignmentsArr.push(consignmentObj);
I might be a n00b , but this code (although i think its fairly verbose ) should work.
Does the $(this).children not identify directly on each() row that it is iterating over?
When i add console.log(consignmentsArr); i get the array within the object as it should be but the values for the parcel object are just repeating the last row of the table.
1: Object
deliName: ""
deliStreet: ""
docType: "Document"
insurance: "None"
parcels: Array[2]
0: Object
chargeValue:"R34.43"
overallPrice:"R43.54"
parcelId:"2"
totalWeight:"65 kg's"
volWeight:"63 kg's"
1: Object
chargeValue:"R34.43"
overallPrice:"R43.54"
parcelId:"2"
totalWeight:"65 kg's"
volWeight:"63 kg's"
Why can I not get the first row values to be added to parcels[0]?
Thanks
Try to declare parcelObj object inside the function.
$.each($('#parcels-added-overview tr'),function (index) {
var parcelObj = new Object();
parcelObj.parcelId = $(this).children('.par-id').text();
parcelObj.totalWeight = $(this).children('.par-weight').text();
parcelObj.volWeight = $(this).children('.par-vol-weight').text();
parcelObj.chargeWeight = $(this).children('.par-charge-weight').text();
parcelObj.overallPrice = $(this).children('.par-price').text();
parcelsArr.push(parcelObj);
});
consignmentObj.parcels = parcelsArr;
consignmentsArr.push(consignmentObj);

get text from attribute and format it

I have a div elements with data-seat and data-row property:
<div class='selected' data-seat='1' data-row='1'></div>
<div class='selected' data-seat='2' data-row='1'></div>
<div class='selected' data-seat='3' data-row='1'></div>
<div class='selected' data-seat='1' data-row='2'></div>
<div class='selected' data-seat='2' data-row='2'></div>
I want print friendly message for selected seats:
var selectedPlaceTextFormated ='';
$(".selected").each(function () {
var selectedPlace = $(this);
selectedPlaceTextFormated += "Row " + selectedPlace.attr("data-row") + " (seat " + selectedPlace.attr("data-seat") + ")\n";
});
alert(selectedPlaceTextFormated);
This code works well and shows the following:
Row 1 (seat 1)
Row 1 (seat 2)
Row 1 (seat 3)
Row 2 (seat 1)
Row 2 (seat 2)
But, I want group seats by row, i.e I want the following:
Row 1(seats: 1,2,3)
Row 2(seats: 1,2)
also, order by row number. How can I do this?
Thanks. DEMO
Here is the code
var selectedPlaceTextFormated ='';
var row_array = [];
$(".selected").each(function () {
var selectedPlace = $(this);
if (!row_array[selectedPlace.attr("data-row")]){
row_array[selectedPlace.attr("data-row")] = selectedPlace.attr("data-seat");
}
else row_array[selectedPlace.attr("data-row")] += ','+selectedPlace.attr("data-seat");
});
for (row in row_array){
alert("Row "+ row +"(seat " + row_array[row] + ")\n" );
}
And here the link to the working fiddle: http://jsfiddle.net/3gVHg/
First of all, jQuery is kind enough to automatically grab data- attributes into its data expando object, that means, you can access those data via:
jQueryObject.data('seat');
for instance.
Your actual question could get solved like
var $selected = $('.selected'),
availableRows = [ ],
selectedPlaceTextFormated = '',
currentRow,
currentSeats;
$selected.each(function(_, node) {
if( availableRows.indexOf( currentRow = $(node).data('row') ) === -1 ) {
availableRows.push( currentRow );
}
});
availableRows.forEach(function( row ) {
selectedPlaceTextFormated += 'Row ' + row + '(';
currentSeats = $selected.filter('[data-row=' + row + ']').map(function(_, node) {
return $(this).data('seat');
}).get();
selectedPlaceTextFormated += currentSeats.join(',') + ')\n';
});
jsFiddle: http://jsfiddle.net/gJFJW/3/
You need to use another variable to store the row, and format accordingly.
var selectedPlaceTextFormated ='';
var prevRow = 0;
$(".selected").each(function () {
var selectedPlace = $(this);
var row = selectedPlace.attr("data-row");
var seat = selectedPlace.attr("data-seat");
if(prevRow == row){
selectedPlaceTextFormated += "," + seat;
}
else{
if(selectedPlaceTextFormated != ''){
selectedPlaceTextFormated += ')\n';
}
selectedPlaceTextFormated += "Row " + row + " (seat " + seat;
prevRow = row;
}
});
selectedPlaceTextFormated += ')\n';
alert(selectedPlaceTextFormated);
Check http://jsfiddle.net/nsjithin/R8HHC/
This can be achieved with a few slight modifications to your existing code to use arrays; these arrays are then used to build a string:
var selectedPlaceTextFormated = [];
var textFormatted = '';
$(".selected").each(function(i) {
var selectedPlace = $(this);
var arr = [];
selectedPlaceTextFormated[selectedPlace.attr("data-row")] += "," + selectedPlace.attr("data-seat");
});
selectedPlaceTextFormated.shift();
for (var i = 0; i < selectedPlaceTextFormated.length; i++) {
var arr2 = selectedPlaceTextFormated[i].split(",");
arr2.shift();
textFormatted += "Row " + (i + 1) + " seats: (" + arr2.join(",") + ")\n";
}
alert(textFormatted);
​
Demo
I'd just do this:
var text = [];
$(".selected").each(function () {
var a = parseInt($(this).data('row'), 10),
b = $(this).data('seat');
text[a] = ((text[a])?text[a]+', ':'')+b;
});
var selectedPlaceTextFormated ='';
$.each(text, function(index, elem) {
if (!this.Window) selectedPlaceTextFormated += "Row " + index + " (seat " + elem + ")\n";
});
alert(selectedPlaceTextFormated);
FIDDLE

Categories