Updating javascript array data via input field - javascript

I'm trying to create a shopping cart that builds an array to send to a server. The part I'm having trouble figuring out is allowing for the user to change the quantity via an input field that updates the 'quantity' value in the basketItems array.
I may be going about this wrong, but hopefully one of you geniuses could help me out.
var basketItems = [
{ itemName:"Item 1", price:1.00, quantity:0 },
{ itemName:"Item 2", price:2.00, quantity:0 },
{ itemName:"Item 3", price:3.00, quantity:0 }
];
var basketItemsTotal = 0.00;
function CalcBasketTotal() {
for (i=0;i<basketItems.length;i++) {
if (basketItems[i].quantity > 0) {
basketItemsTotal = basketItems[i].price * basketItems[i].quantity;
}
}
}
function PopulateBasketItems() {
for (i=0;i<basketItems.length;i++) {
basketTable.innerHTML +=
'<tr><td>' + basketItems[i].itemName + '</td>' +
'<td>$' + basketItems[i].price + '</td>' +
'<td><input value="' + basketItems[i].quantity + '"></td>' +
'<td>$' + basketItems[i].price * basketItems[i].quantity + '</td></tr>';
}
}
BONUS: Eventually, I'm trying to make this script send the server this array along with the total, but first thing's first!

your broblem is here :
function CalcBasketTotal() {
for (i=0;i<basketItems.length;i++) {
if (basketItems[i].quantity > 0) {
basketItemsTotal = basketItems[i].price * basketItems[i].quantity;
}
}
}
fix: (replace = by += to total)
function CalcBasketTotal() {
for (i=0;i<basketItems.length;i++) {
if (basketItems[i].quantity > 0) {
basketItemsTotal += basketItems[i].price * basketItems[i].quantity;
}
}
}

Related

Product Loop Problem in Javascript Categories

We made a category structure where products can be listed without changing the page. However, instead of stopping when the products in the category are exhausted, it first brings the products in the category, and then continues to pull products from another unrelated category. We couldn't find where we went wrong.
loadFsk('{{baseurl}}index.php?route=product/category&path='+selecteds.join('_'));
$.get('{{baseurl}}index.php?route=common/fskcats/search&catid=' + did, function (json) {
for (var i = (step); i < 6; i++) {
$('.seller-subcategories.step' + (i + 1)).remove();
}
if (step == 0) {
$('#catappends').html('');
}
if (json) {
var html = '<div class="seller-subcategories step' + (step + 1) + '"><ul class="seller-sub-ul">';
$(json['categorys']).each(function (k, v) {
html += '<li class="seller-sub-li"><a class="catjs" data-step="'
+ (step + 1) + '" data-id="' + v['category_id'] + '">' + v['name'] + '</a></li>'
});
html += '</ul></div>';
$('#catappends').append(html);
}
}, 'JSON');
});
function loadFsk(url,isnew=false){
$.ajax({
url: url,
dataType:'HTML',
success: function(htmlData){
if (isnew) {
$('.main-products-wrapper .main-products.product-grid').html($(htmlData).find('.product-grid .product-layout'));
}else{
$('.main-products-wrapper .main-products.product-grid').html($(htmlData).find('.main-products-wrapper .main-products.product-grid .product-layout'));
}
$('.pagination-results').html($(htmlData).find('.pagination-results'));
}
});
Journal.infiniteScrollInstance = $.ias({
container: '.main-products',
item: '.product-layout',
pagination: '.pagination-results',
next: '.pagination a.next'
});
}
window.addEventListener('load', () => {
let el = document.querySelector('.seller-horizontal .seller-ul .seller-li.active');
if(el){
let left_value = el.offsetLeft - (window.innerWidth/2) + (el.offsetWidth/2);
el.parentNode.scrollTo({
left: left_value,
behaviour: 'smooth',
});
}
})

How to click through array of objects and display data in div using javascript

I have pages of scrapped data coming from the db and displaying that in a table (which works fine). Then I have another query from the db to only get the error rows from that scrapped data and to display that data in a div in the header. This way the user knows what data to change.
I'm having trouble allowing the user to change pages and then get the first row of that page's error data. Right now what I'm doing is creating an index variable and using that as a count and allowing the user to click through rows one at a time and then it changes to the next page if there is no more error data for that page.
How can I get it so the user is able to change the pages freely and then get the correct rows for that data and be able to click up or down through the objects for that page?
Here is my header where the error data and page header data is stored:
<div id="pageEditDiv">
<div class="arrowIconsDiv">
<img src="images/up-arrow.png" class="arrowIcons" id="arrowUpPage">
<img src="images/down-arrow.png" class="arrowIcons" id="arrowDownPage">
</div>
<div id="pageSummary">
<table id="headerPagesTable">
<thead><tr><th>Page Num</th><th>Type</th><th>Month</th><th>Name</th><th>Reg No.</th><th>Rrc District</th></tr></thead>
<tbody id="pagesTableBody"></tbody>
</table>
</div>
<div id="pagesTable" class="hidden"></div>
</div>
<div id="rowEditDiv">
<div class="arrowIconsDiv">
<img src="images/up-arrow.png" class="arrowIcons" id="arrowUpRow">
<img src="images/down-arrow.png" class="arrowIcons" id="arrowDownRow">
</div>
<div id="editableRowToEdit" contenteditable>
<table id="editableRowTable">
<tbody id="pagesRowToEdit"></tbody>
</table>
</div>
</div>
Here is where I get the error row data:
$.ajax({
type: 'POST',
url: 'qry/getPageReceipts.php',
async: true,
data: {FileId: fileId, PageNum: getPageNum, RowNum: rowNum},
success: function(response) {
recPageData = JSON.parse(response);
//check if data exists or not
recPD = {};
if(recPageData.length == 0) {
recPageDateEmpty = 1;
} else {
//map the data
recPD = recPageData.PageNum.map((x,i) => ({
pageNum: x,
rowNum: recPageData["RowNum"][i],
cName: recPageData["CustomerName"][i],
fName: recPageData["FacilityName"][i],
rrcNum: recPageData["RrcNum"][i],
rrcType: recPageData["RrcNumType"][i],
volume: recPageData["Volume"][i]
}));
//sort the data
recPD.sort(function(a,b) {
if(a.pageNum == b.pageNum) {
return (a.rowNum - b.rowNum);
} else {
return (a.pageNum - b.pageNum);
}
});
for(var i=0; i<recPD.length; i++) {
recPD[i].index = i;
}
}
drawPageForm();
drawRowEditForm();
}
});
Here is where I draw the page summary data for the user to click up and down the pages:
function drawPageForm() {
//clear div to begin with
$(".pagesMonth").html();
$("#pagesTableBody").empty();
var getPages = '<table><thead><tr><th>Page Num</th><th>Type</th><th>Month</th><th>Name</th><th>Reg No.</th><th>Rrc District</th></tr></thead><tbody>';
for(var i=0; i<getPagesResponse.length; i++) {
getPages += '<tr class="getPagesRowEdit"><td>' + getPagesResponse["PageNum"][i] + '</td><td class="pagesPageType">' + getPagesResponse["PageType"][i] + '</td><td class="pagesMonth">' + getPagesResponse["ReportingMonth"][i] + '</td><td class="pagesFilerName">' + getPagesResponse["FilerName"][i] + '</td><td class="pagesFilerRegNo">' + getPagesResponse["FilerRegNo"][i] + '</td><td class="pagesRrcDistrict">' + getPagesResponse["RrcDistrict"][i] + '</td></tr>';
}
getPages += '</tbody></table>';
//add table to div
$("#pagesTable").html(getPages);
//PAGES
//delcare single object for page summary
gPT = {
gPRE : $(".getPagesRowEdit").eq(0),
pNum : $(".getPagesRowEdit").find("td").eq(0).text(),
pTB : $("#pagesTableBody"),
aUP : $("#arrowUpPage"),
aDP : $("#arrowDownPage"),
place : function(row) {
gPT.pTB.empty();
clone = row.clone(true);
clone.appendTo(gPT.pTB);
}
}
//add row to div
gPT.place(gPT.gPRE);
//arrow up
gPT.aUP.on("click", function() {
prev = gPT.gPRE.prev();
gPT.gPRE = prev.is("tr") ? prev : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
});
//arrow down
gPT.aDP.on("click", function() {
next = gPT.gPRE.next();
gPT.gPRE = next.is("tr") ? next : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
});
}
Here is where I draw the row error data for the user to click up and down each row of data for that specific page:
function drawRowEditForm() {
//get the current page type
pageTypeValue = $(".pagesPageType").html();
//empty row
$("#pagesRowToEdit").empty();
//find correct row
recPD.find(findRecPageIndex);
//match row with rawText row
findMatchRowNum = $("#pagesRowToEdit").find("tr").eq(0).find("td").eq(0).text();
findMatchRowNum = findMatchRowNum - 1;
matchedRow = $(".rowToEdit").eq(findMatchRowNum);
matchedRow.addClass("selected");
//scroll div to visible row
$("#textCodeDiv").animate({
scrollTop: $(".selected").offset().top
},'slow');
//click arrow up
$("#arrowUpRow").unbind("click").click(function() {
clickRowArrowUp();
});
//click arrow down
$("#arrowDownRow").unbind("click").click(function() {
clickRowArrowDown();
});
}
function clickRowArrowUp() {
$("#pagesRowToEdit").empty();
if($(".selected")) {
$(".selected").removeClass("selected");
}
recRowIndex--;
if(recPD.find(findRecPageIndex)) {
drawRowEditForm();
} else {
prev = gPT.gPRE.prev();
gPT.gPRE = prev.is("tr") ? prev : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
}
}
function clickArrowDown() {
$("#pagesRowToEdit").empty();
if($(".selected")) {
$(".selected").removeClass("selected");
}
recRowIndex++;
if(recPD.find(findRecPageIndex)) {
drawRowEditForm();
} else {
next = gPT.gPRE.next();
gPT.gPRE = next.is("tr") ? next : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
}
}
//match the row to the error data and display in header
function findRecPageIndex(el) {
if(el.index === recRowIndex && el.pageNum === pageNum) {
return $("#pagesRowToEdit").append("<tr id='recTR'><td class='hidden'>" + el.rowNum + "</td><td>" + el.cName + "</td><td>" + el.fName + "</td><td>" + el.rrcNum + "</td><td>" + el.rrcType + "</td><td>" + el.volume + "</td></tr>");
}
}
function findDelPageIndex(el) {
if(el.index === delRowIndex && el.pageNum === pageNum) {
return $("#pagesRowToEdit").append("<tr id='delTR'><td class='hidden'>" + el.rowNum + "</td><td>" + el.cName + "</td><td>" + el.fName + "</td><td>" + el.rrcNum + "</td><td>" + el.rrcType + "</td><td>" + el.volume + "</td></tr>");
}
}
So a recap: The user can change pages, BUT then they can't click through the error data. The user can change rows and when there is no more error data on that page it will then change pages and display the first error data row.
What I need to know: is how to allow the user to click through the pages freely and then it be able to determine what page num it is and then display that first error row and allowing the user to click through the correct rows for that page.
Try adding this to your page up and down function:
for(var i=0; i<recPD.length; i++) {
if(pageNum == recPD[i].pageNum) {
recRowIndex = recPD[i].index;
break;
}
}
Here you are looping through the data, checking if the page numbers match and then updating the recRowIndex variable to the lowest index of the error row data.
Hope that works!

JS Error with JSON Response Nodes

I have a page that generates a dropdown of options based on a prior selection. Once the parent dropdown is selected, that triggers a AJAX call which returns a JSON response of the child options.
function fetchLines(line) {
// Define vars we will use in this function
var dropdown = '';
// AJAX call to lines/sublines
$.ajax({
url: baseURL + "index.php/Project/fetchLines",
type: 'POST',
cache: false,
dataType: "json",
data: {
lineType: line
},
error: function(err) {
alert(err.statusText);
},
success: function(data) {
dropdown += '<option></option>';
$(data.lines).each(function() {
dropdown += '<optgroup label="' + this.line + '">';
if (this.sublines.options) {
$(this.sublines.options).each(function() {
dropdown += '<option value="' + this.subLine + '">' + this.subLine + '</option>';
});
}
dropdown += '</optgroup>';
});
$('[name=line]').empty().append(dropdown).select2("enable", true).trigger('change');
}
});
}
The issue I am running into is that there are some times no sublines in the JSON response which is causing the function to error out and not show results at all.
TypeError: this.sublines is undefined
JSON Response:
[
{
"line":"Business",
"sublines":{
"options":[
{
"subLine":"Accounts"
}
]
}
},
{
"line":"Consumer",
"sublines":{
"options":[
{
"subLine":"Cause"
},
{
"subLine":"Financial Services"
}
]
}
},
{
"line":"Risk"
}
]
Is there a way I can prevent a missing node subLines from breaking the function?
Ok, don't take it wrong, but it looks like you have no idea what you're doing. Just trying to use variables like they would be magically there.
I think this is what you're trying to do:
var dropdown = '<option></option>';
// iterate over your lines
$.each(data, function(i, line) {
// check id there's sublines (may be needed to check if there's options too)
if (line.sublines) {
// start an opt group only if there's sublines
dropdown += '<optgroup label="' + line + '">';
// iterate over it's options
$.each(line.sublines.options, function(j, option) {
// add the option to the html
dropdown += '<option value="' + option + '">' + option + '</option>';
});
// close the opt group
dropdown += '</optgroup>';
}
});
// replace the select content and trigger a change
$('[name="line"]').html(dropdown).select2('enable', true).trigger('change');
Check if subLine exists previously:
if (this.sublines.options) {
$(this.sublines.options).each(function() {
if (this.subLine)
dropdown += '<option value="' + this.subLine + '">' + this.subLine + '</option>';
});
}
Clearly in your JSON response not all objects from the array have the property sublines. And this is the line which is make the code to fail.
if (this.sublines.options) {
I'd suggest improving it to the following by checking if it has the property or not:
if (this.sublines && this.sublines.options) {
Check for sublines first...
if (this.sublines) {
if (this.sublines.options) {
$(this.sublines.options).each(function() {
dropdown += '<option value="' + this.subLine + '">' + this.subLine + '</option>';
});
}
}
I think you want to achieve something like this:
Fiddle: https://jsfiddle.net/a3bx77vm/3/
var dropdown = '';
for(var i = 0; i < data.length; i ++)
{
dropdown += '<option></option>';
var eachdata = data[i];
dropdown += '<optgroup label="' + eachdata.line + '">';
if(eachdata.sublines)
{
if (eachdata.sublines.options) {
$(eachdata.sublines.options).each(function() {
dropdown += '<option value="' + this.subLine + '">' + this.subLine + '</option>';
});
}
}
dropdown += '</optgroup>';
}
$("#dropdown").append($(dropdown));
The parsing was wrong because the data you get is an array, and it doesn't have property called lines.

How to rerender data in a javascript table orderd by a specific column

By javascript I generate rows for Agents in a table. every row represent an agent. after this I receive live data to update the columns. I have a column called (Calls) and i need to order the agents by calls (live update depending on received data) descending. example
agents ----- calls
Sam ---------13
Al ---------12
Sara---------8
if Sara got the most data by time then she'll be the first.
agents -------calls
Sara----------15
Sam ----------13
Al------------12
and so on ..
this is my row rendering
var $agentRow = '<tr id="agentRow_' + agentId + '"><th scope="row">' + agentName + '</th><td class="calls" id="agentCalls_' + agentId + '">' + outTotalCalls +
'</td><td class="minutes" id="agentMinutes_' + agentId + '">' +
outCallMinutes + '</td>' +
'<td class="averages" id="agentAverage_' + agentId + '">' + averageOutCallTime + '</td></tr>';
//if $agentRow exists invoke setIncomingValuesToAgentsFields else append it to the table
if ($('#agentRow_' + agentId).length) {
setIncomingValuesToAgentsFields('#agentCalls_' + agentId, outTotalCalls);
setIncomingValuesToAgentsFields('#agentMinutes_' + agentId, outCallMinutes);
setIncomingValuesToAgentsFields('#agentAverage_' + agentId, averageOutCallTime);
} else {
$('#agentsTable').append($agentRow);
}
function setIncomingValuesToAgentsFields(elementId, inComingValue) {
var currentElementValue = 0;
if ($(elementId).text() !== "") {
currentElementValue = $(elementId).text();
currentElementValue = parseFloat(currentElementValue);
currentElementValue += inComingValue;
$(elementId).text(currentElementValue);
} else {
$(elementId).text(currentElementValue);
}
}
See the live sample of what you need. After 3 second Al calls become 14, and table rows will be sorted again.
var agents = [
{ name: 'Sara', calls : 15 },
{ name: 'Sam', calls : 13 },
{ name: 'Al', calls : 12 }
];
function to_row(obj){
var tr = $('<tr></tr>');
tr.data('obj', obj);
$('<td>'+obj.name+'</td>').appendTo(tr);
$('<td>'+obj.calls+'</td>').appendTo(tr);
return tr;
}
function table_update(obj){
$('#table tr').each(function(){
var t=$(this);
var o=t.data('obj');
if(o.name==obj.name){
t.remove();
};
if(o.calls>obj.calls){
to_row(obj).insertAfter(t);
}
return t.data('obj');
})
}
agents.sort(function(x,y){
return y.calls - x.calls;
}).forEach(function(o){
to_row(o).appendTo( $('#table') );
});
setTimeout(function(){
table_update( { name: 'Al', calls : 14 } );
}, 3000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="table">
</table>
Hope you will be getting data from server using Ajax call . So If your having the result data in JSON object , then you can sort the data to find out which is having highest value . The follwing functon will help us to sort the data
sortTable:function (property,asc)
{
sampleTableObject = sampleTableObject.sort(function(a, b) {
if (asc) return (a[property] > b[property]) ? 1 : ((a[property] < b[property]) ? -1 : 0);
else return (b[property] > a[property]) ? 1 : ((b[property] < a[property]) ? -1 : 0);
});
}
property is the json object property (here it should be calls) based on which you need to sort .
Pass false to 'asc' to sort in descending order.
Assign sampleTableObject with the result json object and call sortTable() . Then use the sorted object to build the table.

How to sort data of json object and display accordingly in html?

This is my ajax:
$("form").on("submit", function () {
var data = {
"action": "test"
};
data = $(this).serialize() + "&" + $.param(data);
$.ajax({
type: "POST",
dataType: "json",
url: "ajax2.php",
data: data,
success: function (data) {
$("#main_content").slideUp("normal",function(){
//$(".the-return").html("<br />JSON: " + data+"<br/>");
for (i = 0; i < data.length; i++) {
$(".the-return").append("<div class='inside_return'>Name:" + data[i].name + "<br/>Id:" + data[i].id + "<br/>Pricing:" + data[i].rate + "<br/>Postcode:" + data[i].postcode+ "<br/>Reputation:" + data[i].reputation+"<br/>Review Plus:" + data[i].plus+"<br/>Review Negative:" + data[i].neg+"<br/><h1>Availability</h1>Week Morning:" + data[i].weekM+"<br/>Week Afternoon:" + data[i].weekA+"<br/>Week Evening:" + data[i].weekE+"<br/>Weekend Morning:" + data[i].endM+"<br/>Weekend Afternoon:" + data[i].endA+"<br/>Week Evening:" + data[i].endE+"</div>");
//alert(data[i].name)
}
});
}
});
return false;
});
Above is my ajax. Now this is returning result from query that sorts by postcode by default.
Now when the result displayed, I want to let the user to sort it out by reputation, review and so on..How do I do that.
Put it in a simple way, I just need to alter the order by clause in the query so that it can sort by user selection. What's the easiest way to do it please?
How can I manipulate below part where it appends the result to a div called -the-return so that it sorts by whatever key user use?: Note-> I'm presenting the result in <div> block and not in table.
$(".the-return").append("<div class='inside_return'>Name:" + data[i].name + "<br/>Id:" + data[i].id + "<br/>Pricing:" + data[i].rate + "<br/>Postcode:" + data[i].postcode+ "<br/>Reputation:" + data[i].reputation+"<br/>Review Plus:" + data[i].plus+"<br/>Review Negative:" + data[i].neg+"<br/><h1>Availability</h1>Week Morning:" + data[i].weekM+"<br/>Week Afternoon:" + data[i].weekA+"<br/>Week Evening:" + data[i].weekE+"<br/>Weekend Morning:" + data[i].endM+"<br/>Weekend Afternoon:" + data[i].endA+"<br/>Week Evening:" + data[i].endE+"</div>");
WHat I tried:
success: function (data) {
//I used a function to sort//
data.sort(function (a, b) {
var retVal = 0;
switch (sortOption) {
case 1:
retVal = a.property > b.property ? 1 : (a.property < b.property ? -1 : 0);
break;
// .... many cases here
}
return retVal;
});
//sort function ends here//
$("#main_content").slideUp("normal", function () {
for (i = 0; i < data.length; i++) {
$(".the-return").append("<div class='inside_return'>Name:" + data[i].name + "<br/>Id:" + data[i].id + "<br/>Pricing:" + data[i].rate + "<br/>Postcode:" + data[i].postcode + "<br/>Reputation:" + data[i].reputation + "<br/>Review Plus:" + data[i].plus + "<br/>Review Negative:" + data[i].neg + "<br/><h1>Availability</h1>Week Morning:" + data[i].weekM + "<br/>Week Afternoon:" + data[i].weekA + "<br/>Week Evening:" + data[i].weekE + "<br/>Weekend Morning:" + data[i].endM + "<br/>Weekend Afternoon:" + data[i].endA + "<br/>Week Evening:" + data[i].endE + "</div>");
}
});
}
so when a user clicks a button, it fire the sorting function..Sadly it doesn't work..Placing the function within success, doesn't perform search function it was doing earlier without any sort. Even if I placed it outside the function , still doesn't work.
To sort an array, you can use Array.prototype.sort.
Without any arguments, it attempts to sort elements alphabetically, but you can pass in a comparing function instead.
The function will receive two arguments and should return less than 0, 0 or greater than 0 to define where argument 1 should be in relation to argument 2.
Your sorting function should look something like this:
data.responseData.sort(function (a, b) {
switch (sortOption) {
case 1:
a = a.name,
b = b.name;
type = "string";
case 2:
a = a.reputation,
b = b.reputation;
type = "numeric";
// etc
}
if (type == "numeric")
{
// numeric comparison
return a > b ? 1 : (a < b ? -1 : 0);
} else if (type == "string") {
// string comparison
return a.localeCompare(b);
}
// etc
return;
});
localeCompare will compare the strings for you :)

Categories