My javascript doesn't run without alert - javascript

I am having a problem with a block of my code, this section creates boxes of chocolates based on what a user chooses in a previous step and what data is pulled from the database in the api script.
the problem is that it doesn't work without the alert('hi') in it. if i take that out it will just create an empty box without dropping the flavors in it, the flavor the flavors are inserted with the createFlavorArray function.
var product = new Array();
var price = new Array();
var size = new Array();
$(function () {
$.ajax({
type: 'POST',
url: 'phpscripts/api.php',
data: "",
dataType: 'json',
success: function(rows)
{
count = 0;
for (var i in rows)
{
var row = rows[i];
product[count] = row[0];
price[count] = row[1];
size[count] = row[2];
count++;
}
}
});
});
//b = box
//o = option that is inside the box
//nextBoxId is the box id
//nextFlavorId is the option or flavor id
var nextBoxId = 1;
var nextFlavorId = 1;
var orderCap = 0;
var subTotal = 0;
var numOfChocolates = 0;
var numOfBoxes = 0;
$(document).ready(function(){
while (halfPoundBoxes > 0) {
$("#boxes").append('<div id="b'+nextBoxId+'"></div>');
$('#b'+nextBoxId).addClass('div-table-selection');
$('#b'+nextBoxId).append($('#minusBox').clone().attr('id', "m"+nextBoxId));
$('#b'+nextBoxId).append('<div style="display:table-row"></div>');
//call the function to loop through and create the number of flavor options needed
var x = 0;
alert('hi');
while(x < product.length){
if ('1/2lb Box' == product[x]) {
createFlavorArray(size[x], nextBoxId);
subTotal += price[x] * 1;
$('#b'+nextBoxId).attr('title', product[x]);
}
x++;
}
//clone the delete box button and make it visible
$('#m'+nextBoxId).show(500);
$('#b'+nextBoxId).append("<br />");
if (orderCap == 0) {
$('#boxes').append('<div id="msg"><p>If you wish to add another box to your order select the size and click +1 Box.</p></div>');
}
$("#m"+nextBoxId).click(function() {
$(this).parent().remove();
orderCap--;
//if they're ordering zero boxes hide the order button
//remove total price
//remove the message
if (orderCap == 0)
{
document.getElementById('orderBtn').style.display = "none";
$("#msg").remove();
$("#totalPrice").empty();
}
if (orderCap < 10)
{
$("#cap").remove();
$("#addBox").show(500);
}
var y = 0;
while (y < product.length) {
if ('1/2lb Box' == product[y]) {
subTotal -= price[y] * 1;
numOfChocolates -= size[y] * 1;
}
y++;
}
$('#totalPrice').html("<p>Sub Total: " + subTotal + "</p>")
//subtract the new
$('#finalpaypal').val(subTotal);
});
nextBoxId++;
orderCap++;
numOfBoxes++;
$('#totalPrice').html("<p>Sub Total: " + subTotal + "</p>")
halfPoundBoxes--;
}

The reason your code is working only when using an alert(), is that the alert() action is giving your jQuery AJAX request a few seconds to return a value to your success() call back function.
You should move any code which is affected by your callout function, into the callout function also, so that this code runs in the correct order.
Alternatively you could not run your AJAX request asynchronosly by adding async:false, but as #Rocket has commented, this isn't recommended.
$.ajax({
async: false,

You need to put the code in a function and run it after the ajax success is finished
...
$(function () {
$.ajax({
type: 'POST',
url: 'phpscripts/api.php',
data: "",
dataType: 'json',
success: function(rows)
{
count = 0;
for (var i in rows)
{
var row = rows[i];
product[count] = row[0];
price[count] = row[1];
size[count] = row[2];
count++;
}
do_after_ajax();
}
});
});
function do_after_ajax(){
while (halfPoundBoxes > 0) {
$("#boxes").append('<div id="b'+nextBoxId+'"></div>');
$('#b'+nextBoxId).addClass('div-table-selection');
....
}

It looks like you're trying to operate on markup returned by your ajax. That code needs to be moved into the success callback of the ajax request. The reason the alert call makes it work is simply that it delays everything else long enough for the page to finish loading.

Related

Get .length of NEW dynamically added div

6 items are added onload using ajax. Each click, 6 items are being appended.
I want to hide #load-more button if newly added items are less than 6.
How to find the count of newly added items?
I use .length but all items are being counted.
Thanks for your help.
var max = 6;
var NewItems = $(".items").length;
if (NewItems > max) {
$("#load-more").hide();
} else {
$("#load-more").show();
}
var max = 6;
var start = 1;
var winloc = window.location;
$(window).bind('hashchange', function() {
if (winloc.hash === "" || winloc.hash === "#home") {
homeurl = `https://mailliw88.blogspot.com/feeds/posts/default?start-index=${start}&max-results=${max}&alt=json-in-script`;
loadList(homeurl);
}
}).trigger('hashchange')
function more() {
start += max;
loadList(`https://mailliw88.blogspot.com/feeds/posts/default?start-index=${start}&max-results=${max}&alt=json-in-script`);
}
function loadList(url) {
$.ajax({
url: url,
type: 'get',
dataType: "jsonp",
success: function(data) {
if (data.feed.entry) {
datas = data.feed.entry;
var entry = data.feed.entry;
for (var i = 0; i < entry.length; i++) {
postTitle = entry[i].title.$t;
items = '<div class="items"><h2>' + postTitle + '</h2></div>';
document.getElementById('showlists').innerHTML += items;
}
}
var newItems = $(".items").length;
if (newItems > max) {
$("#load-more").hide();
} else {
$("#load-more").show();
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='showlists'></div>
<div id='load-more' onclick="more()">
load more
</div>
Change:
var newItems = $(".items").length;
if (newItems > max) {
To:
if (data.feed.entry.length < 6)
The variable "max" will be out of scope for your "success" method since it's defined outside of it and is an integer type, so you will need to either directly add it, or use an object, like:
var max = {entries: 6};
...
if (data.feed.entry.length < max.entries)
You could add data attributes to the new items with an incrementing id so the final html would look like
<div data-load="1"></div>
<div data-load="1"></div>
...
<div data-load="2"></div>
...
and then in you're js
$(`div[data-load="${Math.max(...$('div').map(item => parseInt(item.attr("data-load"))))}"`)
would get all the latest ajax elements

How do I compare new ajax output with previous using divs?

I decided to build a high/low game in javascript and am running into an issue where the numbers displayed are ahead of what the variables have stored or the exact opposite. I can't seem to get them to match.
EDIT: I figured it out, the code ran before ajax was done causing an offset.
It helps me more when I find answers with the old code to compare with the new so I'll leave the broken code. Updated with working code at the end.
Page that helped me figure out a fix:
Wait for AJAX before continuing through separate function
Original JavaScript:
var y = "0";
var z = "0";
var output_div = document.getElementById("outcome");
var last_ = document.getElementById("val");
var cardVal;
function higher(x) {
var new_ = last_.innerHTML; //getting new value
y = last_.getAttribute("data-old"); //getting old value
console.log("data_old " + y);
z = ajx(); //calling function return the value from which need to compare
console.log("data_new " + z);
if (x === 1) {
if (z > y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
} else {
if (z < y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
}
last_.setAttribute("data-old", new_); //setting old value with current value of div
}
function ajx() {
$.ajax({
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
var img = result[0];
cardVal = result[1];
document.getElementById(\'card\').src = img;
document.getElementById(\'val\').innerHTML = cardVal;
}
});
return cardVal; // return current card value in calling function
}
Updated Working JavaScript:
var lastVal = document.getElementById("lastVal"); //Last played cars value
var wl = document.getElementById("outcome"); //Shows win or lose
var newVal = document.getElementById("currentVal"); //Current face up card
var iSrc = document.getElementById("card"); //Card img
var lVal; //Last cards value from post
var iLink; //Image link from post
var nVal; //Gets new html to be sent to post.
function start(x){
// console.log("Start:");
ajx(function(){ //Runs ajax before continuing
iSrc.src = iLink; //Set new card image src
newVal.innerHTML = nVal; //Sets Current card value in div
lastVal.innerHTML = lVal; //Sets Last card value in div
// console.log("-slgn"); //Consoles to track code launch order.
// console.log("-Last Value: "+lVal);
// console.log("-Current Value: "+nVal);
// console.log("-Link: "+iLink);
// console.log(x);
if(x===1){ //If clicked higher
if(nVal>lVal){ //If new card is higher than old card
wl.innerHTML = "Winner!";
}else{
wl.innerHTML = "Loser!"
}
}
if(x===2){
if(nVal<lVal){ //If new card is lower than old card
wl.innerHTML = "Winner!";
}else{
wl.innerHTML = "Loser!"
}
}
});
}
function ajx(callback) {
$.ajax({
type: "POST",
data: {data:newVal.innerHTML}, //Post new card value to be returned as last card.
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
iLink = result[0]; //img
lVal = result[2]; //Last card
nVal = result[1]; //New Card
// console.log("ajax");
callback(); //Go back and the code
}
});
}
You can use custom attribute in your div to save your current value as old value and vice versa so only one div required here i.e: Your div look like below :
<div data-old="0" id="val">0</div>
And js code will look like below:
var y = "0";
var z = "0";
var output_div = document.getElementById("outcome");
var last_ = document.getElementById("val");
function higher(x) {
var new_ = last_.innerHTML; //getting new value
y = last_.getAttribute("data-old"); //getting old value
console.log("data_old " + y);
z = ajx(); //calling function return the value from which need to compare
console.log("data_new " + z);
if (x === 1) {
if (z > y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
} else {
if (z < y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
}
last_.setAttribute("data-old", new_); //setting old value with current value of div
}
function ajx() {
$.ajax({
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
var img = result[0];
var cardVal = result[1];
document.getElementById('card').src = img;
document.getElementById('val').innerHTML = cardVal;
}
});
return cardVal; // return current card value in calling function
}
In above js code what i done is after ajax call finishes execution it will return cardVal which will get pass in variable z and then we will compare it with y i.e : old value and print required output.Also, i have return value from ajax called because when you do document.getElementById(\'val\').innerHTML = cardVal; still this value is not available with us in our function higher so to overcome this i have return that value to your calling function.
(This code is already tested and working as excepted )

Can't stop ajax call by clicking cancel button

I have a jQuery script. The concept is, when I am clicking a button, it's first calling an AJAX function to count the no. of rows from a particular query. Then on successful call it stores the number of rows in a jQuery variable.
Then it calls an AJAX function which runs repeatedly to call data from server with 10 rows per time, during this process there is a progress bar which increases or fills gradually each time some data is fetched from the db. when a chunk of data is received, its getting pushed in a global array. When the last ajax call returns blank no. or rows, then the process terminates.
Besides there is a button along with the progress loader, which when will be clicked, will terminate the AJAX process to stop the call and display the data received till now in a data-table.
Here's my script
<script type="text/javascript">
var oTable;
var outer_start_row = 0;
var outer_limit = 1;
var final_data = [];
var cancel = false;
var total_data = 0;
$(document).ready(function() {
window.prettyPrint() && prettyPrint();
$('#load').click(function()
{
var v = $('#drp_v').val();
var cnt = $('#drp_cnt').val();
var ctg = $('#drp_ctg').val();
var api = $('#drp_api').val();
var nt = $('#drp_nt').val();
alert("version :"+v+" category :"+ctg+" country :"+cnt);
$.post("ajax.php",
{
'version':v,'category':ctg,
'country':cnt,'network_id':nt,
'api':api,'func':'total_data'
},
function(data)
{
total_data = data;
$("#progress_bar_container").fadeIn('fast');
});
load_data_in_datatable();
});
});
function stop_it()
{
cancel == true;
}
function load_data_in_datatable()
{
if(cancel == true)
{
alert(cancel);
return;
}
else
{
var v = $('#drp_v').val();
var cnt = $('#drp_cnt').val();
var ctg = $('#drp_ctg').val();
var api = $('#drp_api').val();
var nt = $('#drp_nt').val();
$.post("ajax.php",
{
'version':v,'category':ctg,
'country':cnt,'network_id':nt,
'api':api,'func':'show_datatable',
'start_row':outer_start_row,'limit':outer_limit
},
function(response)
{
var data = response.data;
var limits = response.limits;
outer_limit = limits.limit;
outer_start_row = limits.start_row;
if(data.length > 0)
{
for(var i = 0; i < data.length; i++)
{
final_data.push(data[i]);
}
var current = parseInt(final_data.length);
percent_load = Math.round((current/parseInt(total_data))*100);
$(".progress-bar").css("width",percent_load+"%");
$(".progress-bar").text(percent_load+"%");
load_data_in_datatable();
}
else
{
create_datatable();
cancel = true;
return;
}
},'json');
}
}
function create_datatable()
{
$("#progress_bar_container").fadeOut('fast');
var aColumns = [];
var columns = [];
for(var i = 0; i < final_data.length; i++)
{
if(i>0)
break;
keycolumns = Object.keys(final_data[i]);
for(j = 0; j < keycolumns.length; j++)
{
if($.inArray(keycolumns[j],aColumns.sTitle)<=0)
{
aColumns.push({sTitle: keycolumns[j]}) //Checks if
columns.push(keycolumns[j]) //Checks if
}
}
}
var oTable = $('#jsontable').dataTable({
"columns":aColumns,
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"aButtons": [
{
"sExtends": "csv",
"sButtonText": "CSV",
}
]
}
});
oTable.fnClearTable();
var row = []
for(var i = 0; i < final_data.length; i++)
{
for(var c = 0; c < columns.length; c++)
{
row.push( final_data[i][columns[c]] ) ;
}
oTable.fnAddData(row);
row = [];
}
}
</script>
The problem, is that I can't stop the AJAX when clicking on the cancel button.
function stop_it() {
cancel == true;
}
This function seems to be wrong, you need to assign true to the cancel variable but you have mistakenly written comparison operator(equal to/==) instead it should be:
function stop_it() {
cancel = true;
}
I think you are calling this function while stopping AJAX in between the process.
check link describe how you abort(stop/cancle) ajax request.
Jquery allows you to stop ajax request with .abort() method.
Aborting an AJAX request

Ajax's PHP into while just working once

The code i'm trying to get to work is part of a price list of products from a db. It works almost all of it but i need one ajax to run multiple times, and it does, it even runs the success sentences but when i check the db its like it just ran once... i hope you can help me.
I take 2 values from inputs which are id and amount of the product, and i add them to the list when a button calls the send function, this is that part of the code:
function valores(cod, cant) {
if (cod != '') {
cot.push([cod, cant]);
i++;
}
return cot;
}
function send () {
event.returnValue=false;
var id = $('#id').val();
var amount = $('#cant').val();
var total;
if ($('#total').length > 0) {
total = document.getElementById('total').value;
} else {
total = 0;
}
$.ajax({
type: 'POST',
data: ({cod : id, cant : amount, tot : total }),
url: 'process/agprods.php',
success: function(data) {
$('#totals').remove();
$('#prodsadded').append(data);
valores(id, amount);
rs = $(document.getElementById('rs').html);
},
error: function () {
$('#rs').innerHTML = rs;
document.getElementById('note').innerHTML = "Error: The product doesn't exist.";
$('#handler-note').click();
}
});
}
(I translated some words to english that are originaly in spanish and to make it more readable to you)
So, the cot[] array keeps the product's id and amount, to use them in the next code, which runs when the list is complete and you hit a save button that calls this function:
function ncotiza () {
event.returnValue=false;
var nlist = $('#codp').val();
var day = $('#days').val();
$.ajax({
async: false,
type: 'POST',
data: ({listnumber: nlist, days : day}),
url: 'process/ncot.php'
});
j = 0;
while (j <= i) {
if (cot[j][0] != 0 && cot[j][1] != 0) {
var num = cot[j][0];
var cant = cot[j][1];
$.ajax({
async: false,
type: 'POST',
data: ({ listnumber : nlist, prodid: num, amount : cant }),
url: 'process/ncotpro.php',
success: function () {
alert('Success');
}
});
cot[j][0] = 0;
cot[j][1] = 0;
j++;
}
if (j == i) {
window.location.reload(1);
alert("Finished Successfully");
};
}
}
And it all runs fine, here's the PHP:
(ncot.php)
$listnumber = isset($_POST["listnumber"]) ? $_POST["listnumber"] : '';
$days = isset($_POST["days"]) ? $_POST["days"] : '';
$cons = "INSERT INTO pricelist (listnumber, diashabiles, cdate)
VALUES ('$listnumber', '$days', CURDATE())";
mysql_query($cons);
?>
(ncotpro.php)
$listnumber = isset($_POST["listnumber"]) ? $_POST["listnumber"] : '';
$prodid = isset($_POST["prodid"]) ? $_POST["prodid"] : '';
$amount = isset($_POST["amount"]) ? $_POST["amount"] : '';
$cons = "SELECT price, um
FROM inventory
WHERE listnumber = ".$prodid;
$result = mysql_query($cons) or die ("Error: ".mysql_error());
$row=mysql_fetch_assoc($result);
$umcons = mysql_query("SELECT uvalue FROM um WHERE id = ".$row["um"]) or die ("Error:".mysql_error());
$umres = mysql_fetch_assoc($umcons);
$vuum = $umres["uvalue"];
$fprice = $row["price"] * ($amount * $vuum);
$cons = "INSERT INTO cotpro (cotizacion, producto, amount, monto)
VALUES ('$listnumber', '$prodid', '$amount', '$fprice')";
mysql_query($cons) or die ("Error: ".mysql_error());
?>
The first ajax runs ok, then it also does the one that's inside the while, and it throw all the alerts but when i check the db it just made 1 row and not all it has to.
I'm sorry if it's too obvious or something, i've look a lot of questions and answers in this page and i've been trying to fix this for hours but i just dont see it.
Thank you beforehand.
Try to debug the 2nd jquery file via firebug.
what the value you return in i
while (j <= i) {
..
..
.

How to call ajax on fly for implementing pagination

I have the following javascript code having class named as PurchaseHistory.
var baseUrl = null;
var parameters = null;
var currentPageNumber = null;
var TotalPages = null;
var PageSize = null;
$(document).ready(function () {
baseUrl = "http://localhost/API/service.svc/GetOrderHistory";
parameters = '{"userId":1 , "page":1 ,"pageSize":4}';
currentPageNumber = 1;
var history = new PurchaseHistory();
history.ajaxCall(parameters);
});
function PurchaseHistory() {
/* On ajax error show error message
-------------------------------------------------*/
this.onAjaxError = function() {
$('#error').text('No internet connection.').css('color', 'red');
}
/* Ajax call
-------------------------------------------------*/
this.ajaxCall = function (parameters) {
$.support.core = true;
$.ajax({
type: "POST",
url: baseUrl,
data: parameters,
//dataType: 'json',
contentType: "application/json; charset=UTF-8",
error: function () { this.onAjaxError() }
}).done(function (data) {
var json = data.GetOrderHistoryResult;
var jsonObject = $.parseJSON(json);
var history = new PurchaseHistory();
history.populateOrderHistory(jsonObject);
TotalPages = jsonObject.PgCnt;
currentPageNumber = jsonObject.CrntPg;
});
}
this.populateOrderHistory = function(results) {
var rowOutput = "";
var his = new PurchaseHistory();
for (var i = 0; i < results.Results.length; i++) {
rowOutput += this.renderCartList(results.Results[i], 1);
}
}
this.renderCartList = function(res, i) {
var container = $('#prototype-listelement>li').clone();
container.find('.order-date').text(res.OdrDate);
container.find('.item-count').text(res.Qty);
container.find('.total').text(res.Amt);
container.find('.order-id').text(res.OdrId);
$('#mainul').append(container).listview('refresh');
}
this.loadNextPage = function () {
parameters = '{"userId":1 , "page":' + currentPageNumber + 1 + ',"pageSize":4}';
this.ajaxCall(parameters);
}
}
The ajaxCall is made on the ready function of the javascript.
This ajax calls returns Json object with pages information, which includes current page number, total pages and page size.
Currently I am able to display the information on the UI, when the page gets loaded.
My Issue:-
I want to call the ajax method again, on the button click event.
How this can be made possible and where can I store the information obtained from previous ajax call?
For pagination I would create a link that will load more items onto the page, and save a starting number to pass to your data layer. This example loads 20 at a time.
<a class="more" href="#" data-start="0">show more</a>
$("a.more").click(function(e){
e.preventDefault();
var start = $(this).attr('data-start');
$.get('/more-data, { start: start }, function(d){
var next = start+20;
$("a.more").attr('data-start', next);
//process results here, do something with 'd'
});
});

Categories