Calling a function with AJAX - javascript

I'm not sure how to explain this completely, but I hope this will make sense.
I have a function that I've made that calculates the remaining amount to spend to qualify for free delivery when the basket value total falls within certain thresholds.
The basket value is updated with AJAX every time a product is added to the basket.
The add to basket button appears in an AJAX generated modal.
I need my function to be called on every page refresh and also every time a product is added to the basket when the AJAX generated add to basket button is clicked. I'm trying to do all of this with the below, but it doesn't seem to work correctly. One of the problems is that the event fires multiple times when the add to basket button is clicked and another is that the basket total is updated after the event and so the total isn't calculated correctly.
Can anyone explain how I would tidy all off this up?
function totalBag() {
var standardDeliveryLow = 49.99;
var standardDeliveryHigh = 64.99;
var expressDeliveryLow = 65.00;
var expressDeliveryHigh = 99.99;
var bagValue = $('#basket-value').text();
var bagTotal = Number(bagValue.replace(/[^0-9\.-]+/g,""));
if (bagTotal >= standardDeliveryLow && bagTotal <= standardDeliveryHigh) {
var standardDifference = parseFloat(Math.round((standardDeliveryHigh - bagTotal) * 100) / 100).toFixed(2);
$('<div class="delivery-message"><p>£'+ standardDifference +' from standar delivery</p></div>').insertAfter('.breadcrumbs');
} else if (bagTotal >= expressDeliveryLow && bagTotal <= expressDeliveryHigh) {
var expressDifference = parseFloat(Math.round((expressDeliveryHigh - bagTotal) * 100) / 100).toFixed(2);
$('<div class="delivery-message"><p>£'+ expressDifference + ' from express delivery</p></div>').insertAfter('.breadcrumbs');
} else {
return false;
}
}
$(document).on('ajaxSuccess', function(e) {
$('[name="AddItemToBasket"]').on('click', function() {
$('body').bind('ajaxSuccess.custom', function() {
totalBag();
//alert('this works');
$(this).unbind('ajaxSuccess');
});
});
});
totalBag();

EDIT: Have fixed the issue where text was duplicating. Also have added comments for more understanding.
Had a check at the link you specified and tried the following modified code.
As per #ADyson, have removed the click event, which is fixing the multiple event firing.
Regarding your other problem, the total is updated after the event, yes the HTML is getting updated after the ajaxSuccess is triggered. Hence have used the ajaxSuccess event itself to get the basket amount and use it in totalBag fn.
It seems to be working. Kindly confirm:
//Adding empty div so that we can just update the value later
$(document).on('ready', function(){
$('<div class="delivery-message"></div>').insertAfter('.breadcrumbs');
})
function totalBag(bagTotal) {
var standardDeliveryLow = 49.99;
var standardDeliveryHigh = 64.99;
var expressDeliveryLow = 65.00;
var expressDeliveryHigh = 99.99;
//var bagValue = $('#basket-value').text();
//var bagTotal = Number(bagValue.replace(/[^0-9\.-]+/g,""));
//Using a variable to store the calculated amount with text
var innerHTML = "";
if (bagTotal >= standardDeliveryLow && bagTotal <= standardDeliveryHigh) {
var standardDifference = parseFloat(Math.round((standardDeliveryHigh - bagTotal) * 100) / 100).toFixed(2);
innerHTML= "<p>£"+ standardDifference +" from standar delivery</p>";
} else if (bagTotal >= expressDeliveryLow && bagTotal <= expressDeliveryHigh) {
var expressDifference = parseFloat(Math.round((expressDeliveryHigh - bagTotal) * 100) / 100).toFixed(2);
innerHTML= "<p>£"+ expressDifference +" from express delivery</p>";
} else {
return false;
}
//Updating the placeholder with new contents
$(".delivery-message").html(innerHTML);
}
//Gets triggered after every Ajax Success.
//e -> event object, xhr -> The Ajax object which has request and response details,
//settings -> The settings we used to trigger Ajax, including the request URL
$(document).on('ajaxSuccess', function(e, xhr, settings) {
//Checking if the request is of Adding Item to Basket
if(settings.url.indexOf("AddItemToBasket") !== -1){
//Getting the response and parsing it
var resp = xhr.responseText;
var respObj = JSON.parse(resp);
//Checking if response is success i.e., item added to cart successfully
if(respObj.success){
//Getting the updated Basket value and calling totalBag
var bagTotal = respObj.basket.subTotal;
totalBag(bagTotal);
}
}
});
totalBag(0);

Related

Random button generator needs fixing to avoid loading the same page

I have a random button generator, named 'next event'. The button is okay however needs an improvement. Sometimes this button loads the same page the user is on multiple times, I'm not sure how to edit this, this is my code.
I could remove the current pages URL, however, this is in a separate JS document and I would like that to be loaded again on further button clicks.
the code used:
var sites = [
'/landingpage/events/uk/boardmasters.html',
'/landingpage/events/uk/reading.html',
'/landingpage/events/uk/rizefest.html',
'/landingpage/events/uk/bestival.html',
'/landingpage/events/uk/creamfields.html',
'/landingpage/events/uk/feastival.html',
'/landingpage/events/uk/fusion.html',
];
function randomSite() {
var i = parseInt(Math.random() * sites.length);
location.href = sites[i];
}
Like this:
function randomSite() {
var i = parseInt(Math.random() * sites.length);
if(location.href !== sites[i])
location.href = sites[i];
else randomSite();
}
UPDATE
Based on the comment if you deleted URL within array I would change the function accordingly. And you don't need pop()
function randomSite() {
var i = parseInt(Math.random() * sites.length);
if(location.pathname !== sites[i])
location.pathname = sites[i];
else randomSite();
}
You could remove the current page from the pages-array before choosing a random item from it:
function randomSite() {
var index = sites.indexOf(window.location.href);
if (index > -1) {
sites.splice(index, 1);
}
var i = parseInt(Math.random() * sites.length);
location.href = sites[i];
}

Populating a text box with the results of a calculation

I have this form where a user enters price and quantity, soon after the mouse leaves the 'Quantity' text box, I want the TotalPrice text box to be populated with result of Price * Quantity. The following is my jQuery code, however the TotalPrice text box does not get populated with the result. Hope someone can advise me on how to go about getting it right.
$("#quantity").mouseleave (function () {
var i = $("#price").val();
var k = $("#quantity").val();
var total = i*k;
$("#totalprice").val(total);
});
You need to use blur event handler of those two textboxes. Try this:
$(document).ready(function() {
$("#price").on("blur", calculate);
$("#quantity").on("blur", calculate);
//If you want to do the calculation when the page renders:
calculate();
});
function calculate(){
var i = $("#price").val();
var k = $("#quantity").val();
var total = i*k;
$("#totalprice").val(total);
}
As trincot mentioned in the comment below, you can merge the two events in one line since they call the same function:
$("#price, #quantity").on("blur", calculate);
I think you want this
jQuery(document).ready(function($) {
var price = $("#price");
var qty = $("#quantity");
var total = $("#totalprice");
/* CREATE VARIABLES ON DOCUMENT READY,
BECAUSE YOU WANT TO CACHE THE DOM SELECTION */
qty.on("blur", function(){
var i = price.val();
var k = qty.val();
total.val(i * k);
});
});
working fiddle ==> https://jsfiddle.net/tonysamperi/xqxm3900/
The problem with your code is that it is getting executed ONLY ONCE as soon as the ready function is called.
You need to attach a listner to the action element
$(document).ready(function() {
$("#quantity").mouseleave(function(){
var i = $("#price").val();
var k = $("#quantity").val();
var total = i*k;
$("#totalprice").val(total);
});
});
You can use various event listners such as onchange, onfocusout, blur, onkeyup depending on how and when you want the changes to happen. For more info on types of events and all for jquery only - https://api.jquery.com/category/events/

pageinit code executing fine but elements do not update with content and click events do not work

Original loading of the page seems to work fine. Navigating from another page back to the .index page has the issue. The pageinit code executes fine, all values are calculated fine in the calculate method. However elements are not updated and click event is broken. Change events no longer fires when values change.
index.js file
$(document).on("pageinit", ".index", function () {
getElement("btnCalculate").addEventListener("click", calculate, false);
$("#txbGrossIncome").change(function () {
store.set("grossIncome", getElement("txbGrossIncome").value);
});
$("#txbTaxRate").change(function () {
store.set("taxRate", getElement("txbTaxRate").value);
});
calculate();
});
function calculate() {
var grossIncome = parseFloat(store.get("grossIncome"));
var taxRate = parseFloat(store.get("taxRate"));
if (grossIncome) {
getElement("txbGrossIncome").value = grossIncome;
}
else {
grossIncome = parseFloat(getElement("txbGrossIncome").getAttribute("placeholder"));
}
if (taxRate) {
getElement("txbTaxRate").value = taxRate;
}
else {
taxRate = parseFloat(getElement("txbTaxRate").getAttribute("placeholder"));
}
var netIncome = grossIncome - (grossIncome * (taxRate / 100))
var totalExpenses = calcExpenses();
var totalBudget = calcBudget(netIncome, totalExpenses);
getElement("txtTotalExpenses").innerHTML = "$" + totalExpenses.toFixed(2);
getElement("txtBudget").innerHTML = "$" + (totalBudget / 12).toFixed(2);
}
I'm not sure what is causing this behavior. Any ideas? I can send a private link to where this is hosted if necessary to observe the behavior.

Cordova navigator.app.backHistory button on html different approach

I'm building hybrid app with Intel XDK and I need help with back button and it's function. I have only one index.html file. All "pages" are 's and each one have different id.
I navigate through them using activate_subpage("#uib_page_10");
$(document).on("click", ".firs_div_button", function(evt){
//#uib_page_10 is div with it's content
activate_subpage("#uib_page_10");
var thisPage = 1;
goBackFunction (thisPage); //call function and pass it page number
});
$(document).on("click", ".second_div_button", function(evt){
//#uib_page_20 is div with it's content
activate_subpage("#uib_page_20");
var thisPage = 2;
goBackFunction (thisPage); //call function and pass it page number
});
I have set this EventListener hardware on back button.
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
alert("hello");
navigator.app.backHistory();
}
This is functional but it does not work as it should, in my case and for my app.
When I navigate from one page to another (5 pages / divs) and hit back button, sometimes it does not go back to the first page. It just go "back" to history too deep and close the app, without changing the actual page (view) before closing.
Now, I have an idea, but I need help with this.
I will not use history back, I will use counter and dynamic array for up to 5 elements.
function goBackFunction (getActivePage) {
var active_page = getActivePage;
var counter = 0; // init the counter (max is 5)
var history_list = [counter][active_page]; // empty array
counter = counter + 1;
:
:
:
}
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
//read the array and it's positions then activate:
activate_subpage("#PAGE_FROM_ARRAY");
counter = counter - 1;
if (counter == 0) {
//trigger the app exit when counter get's to 0.
navigator.app.exitApp();
}
}
This is only idea, not tested. I would like to store list of opened pages in Array and when back button is pressed, to activate the pages taken from the Array list, backwards.
I do not know how to do this, I'm not a expert :( There is may be batter way to do this. If someone have any suggestion, I will accept it :D
I save an array in localStorage with all pages navigated and I go back using a pop() on the array. At the moment, it's the best way I got to go back.
This is my code:
// First, create the table "pages"
function init_pages_table()
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.isNew())
{
pages.drop();
pages.commit();
}
var pages = new localStorageDB("pages", localStorage);
pages.createTable("Pages", ["nome"]);
// commit the database to localStorage
// all create/drop/insert/update/delete operations should be committed
pages.commit();
}
// Add a page into the array:
function push_pagename(pagename)
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.tableExists("Pages"))
{
init_pages_table();
pages = new localStorageDB("pages", localStorage);
}
pages.insert("Pages", {nome: pagename});
pages.commit();
}
// Pop a page form the array:
function pop_pagename()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
var rowdeleted = pages.deleteRows("Pages", {ID: id_page});
pages.commit();
return output;
}
You can also define functions for set, get, read:
function set_backpage(pageurl)
{
push_pagename(pageurl);
}
function get_backpage()
{
return pop_pagename();
}
function read_backpage()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
return output;
}

Click event object tracking woes

So I am working on this but of jQuery that gets the element id through a click event. This then triggers a function that acts like the deprecated .toggle()- it slides an element down on the fist click and slides that element up on the second click. However, there is a bug that causes the element to slide up and down the amount of times that it has been clicked on. For instance, if this is the second time I use the .clickToggle function, the element (table) slides up and down twice before settling, and so on. I suspect it has something to do with the event object, e, tracking the number of clicks-- i.e. I probably shouldn't set id = e.target.id-- but I'm not sure how to fix while still getting the relevant element id that I need.
Here is the relevant clickToggle plug in (courtesy of an answer here on stackoverflow).
(function($) {
$.fn.clickToggle = function(func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function() {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
}(jQuery));
Here is the buggy code that fits the above description.
$(document).click(function(e) {
//get the mouse info, and parse out the relevant generated div num
var id = e.target.id;
var strId = id.match(/\d$/);
//clickToggle the individual table
$('#showTable' + strId).clickToggle(function () {
$('#table' + strId).slideDown();
$('#table' + strId).load('files.php');
},
function () {
$('#table' + strId).slideUp();
});
});//close mousemove function
Any help would be much appreciated. Thanks.
The problem is that you're registering a new click handler for the element each time you invoke clickToggle:
this.click(function() {...
On each subsequent click, you add another handler, as well as invoking all previous handlers. Bleagh.
Better to be straightforward: (DEMO)
var showTable = function($table) {
$table.slideDown();
$table.load('files.php');
$table.removeClass('hidden');
};
var hideTable = function($table) {
$table.slideUp();
$table.addClass('hidden');
};
$(document).click(function (e) {
//get the mouse info, and parse out the relevant generated div num
var id = e.target.id;
var strId = id.match(/\d$/)[0];
var $table = $('#table' + strId);
if ($table.hasClass('hidden')) {
showTable($table);
} else {
hideTable($table);
}
});

Categories

Resources