Set AJAX response as javascript variable for reuse [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
EDIT : found the solution, i edited the code so if anyone came to the same problem in a near future can copy my code.
I need to set AJAX response as variable so i can use it on next js script. how can i set AJAX response to variable?
i don't really good at javascript so it might be just typo or something.
this is my code
<script type="text/javascript">
var delivery; // declare of variable to make it "global"
$(document).ready(function() {
$("#jumlah").bind("input change paste keyup", function() {
var qty = $(this).val();
$.ajax({
type: 'POST',
url: '../component/quantity.php',
data: {
jumlah: qty,
id:<?php echo $hasil['id']; ?>
},
success: function (response) {
// We get the element having id of display_info and put the response inside it
delivery = parseFloat(response); // remove the "var" here so you take the cur variable and don't set a new one in the scope of this function.
}
});
});
});
</script>
<script type="text/javascript">
$(document).ready(function() {
$("select").change(function() {
var total = delivery;
$('select option:selected').each(function() {
total += parseFloat($(this).data('price'));
});
var updatePrice = document.getElementById('jumlah').value;
var grandTotal = total * updatePrice;
$(".total").val(grandTotal);
$(".total").html(grandTotal.toLocaleString());
});
$("#jumlah").bind("input change paste keyup", function() {
var total = delivery;
$('select option:selected').each(function() {
total += parseFloat($(this).data('price'));
});
var updatePrice = $(this).val();
var grandTotal = total * updatePrice;
$(".total").val(grandTotal);
$(".total").html(grandTotal.toLocaleString());
});
});
</script>

What you are looking for are scopes. Depending on how and where you set a variable the scope changes.
In your case you want one that is accessable globally so you should place it at the top. You just need to declare it, you don't need to assign any value.
<script type="text/javascript">
var delivery; // declare of variable to make it "global"
$(document).ready(function() {
$("#jumlah").bind("input change paste keyup", function() {
var qty = $(this).val();
$.ajax({
type: 'POST',
url: '../component/quantity.php',
data: {
jumlah: qty,
id:1
},
success: function (response) {
// We get the element having id of display_info and put the response inside it
delivery = parseFloat(response); // remove the "var" here so you take the cur variable and don't set a new one in the scope of this function.
}
});
});
});
</script>
2nd part
<script type="text/javascript">
$(document).ready(function() {
$("select").change(function() {
var total = delivery;
$('select option:selected').each(function() {
total += parseFloat($(this).data('price'));
});
var updatePrice = document.getElementById('jumlah').value;
var grandTotal = total * updatePrice;
$(".total").val(grandTotal);
$(".total").html(grandTotal.toLocaleString());
});
$("#jumlah").bind("input change paste keyup", function() {
var total = delivery;
$('select option:selected').each(function() {
total += parseFloat($(this).data('price'));
});
var updatePrice = $(this).val();
var grandTotal = total * updatePrice;
$(".total").val(grandTotal);
$(".total").html(grandTotal.toLocaleString());
});
});
</script>
Edit: Fixed the code. The variable has to be outside of a function.

The window object represents an open window in a browser.
window is a object and you can add any property to window.
success: function (response) {
window.deliveryResponse = response;
}
So you can use this response in any other js file.
other.js
(window.deliveryResponse) && console.log(window.deliveryResponse)

As ajax calls are async, you cannot be sure that the delivery variable will be undefined or not.
In your case, this cannot work also because the variable is defined in the callback scope. To ensure that the delivery response is defined, create a function like this:
function onDelivery(delivery) {
....(rest of second script)
}
Pass this function to the success and use delivery as it is.

Try this:-
<script type="text/javascript">
var delivery; // make your variable delivery as global so you can use it where you want.
$(document).ready(function() {
//you can use it here or anywhere in script you want to re-use it.
//put your code as per your functionality.
});
</script>

Related

use multiple $(function() with ajax live search

I created a live search. When i open up the page i want to run $(function() {. This run the ajax once and all the output shown up. But i want that it is also updating the page when i type in the searchbox(thats why i used this $('#search').keyup(function(){). AND i want that it update the page also when i press one of the checkboxes which add some other values to the livesearch($('.btn').click(function(){)
$(document).ready(function(){
$(function() {
$('#search').keyup(function(){
var search = $(this).val();
console.log("Input: " + search);
$('.btn').click(function(){
let val1 = getval1();
let val2 = getval2();
let val3 = getval3();
let val4 = getval4();
console.log(val1 + val2 + val3 + val4)
$.ajax({
url:"search.php",
method:"post",
data:{
search:search,
val1:val1,
val2:val2,
val3:val3,
val4:val4,
},
success:function(data){
$('#output').html(data);
}
});
});
});
});
$(document).ready(function(){
//page completed loading
$('#search').keyup(function(){
//user typed something
var search = $(this).val();
let val1 = getval1();
let val2 = getval2();
let val3 = getval3();
let val4 = getval4();
//let's retrieve values
$.ajax({
url:"search.php",
method:"post",
data:{
query:query,
search:search,
val1:val1,
val2:val2,
val3:val3,
val4:val4
},
success:function(data){
$('#output').html(data);
}
});
});
That is enough. You don't even need to use click event since it will fire on each type. Otherwise you can use the click instead of the keyup and it will fire on button click.
Each time you will type something into #search, you will check the value of the other fields too. I'm curious to see what is inside each getval fucntion beacuse probably they can be replaced by something simpler (btw no need for four different functions imho)
Note: $(document).ready(){}; is used to tell the browser to wait the full page to be loaded before executing the code. You will have one of these only in your page with all the js inside. The functions you define (like when you do
function getval1(){
//your function here
}
don't need to be inside the document ready statement
<script type="text/javascript">
search_data()
$(document).ready(function(){
$('#search').keyup(function(){
search_data()
});
$('.btn').click(function(){
search_data()
});
});
function search_data(query){
var search = $('#search').val();
let val1 = getval1();
let val2 = getval2();
let val3 = getval3();
let val4 = getval4();
$.ajax({
url:"search.php",
method:"post",
data:{
query:query,
search:search,
val1:val1,
val2:val2,
val3:val3,
val4:val4,
},
success:function(data){
$('#output').html(data);
}
});
}
</script>

How to restore Jesson's value and put it into outside variable

I have a problem with this code
I manage to take the values from the json and put them into variables but I can not use them outside the function
what am i doing wrong ?
var sensor_name1;
var lat1;
var lng1;
var sensor_name2;
var lat2;
var lng2;
var sensor_name3;
var lat3;
var lng3;
$(function (){
var $sensors = $('#sensors');
$.ajax({
type:'GET',
url:'http://127.0.0.1:5000/',
success: function(sensors){
$.each(sensors, function(i, sensor) {
if (i==0){
$sensors.append(sensor_name1=sensor.name, lat1=sensor.lat, lng1=sensor.lng);
}
if(i==1){
$sensors.append(sensor_name2=sensor.name, lat2=sensor.lat, lng2=sensor.lng);
}
if (i==2){
$sensors.append(sensor_name3=sensor.name, lat3=sensor.lat, lng3=sensor.lng);
}
});
console.log('sensor one : ',sensor_name1, lat1, lng1);
console.log('sensor tow : ',sensor_name2, lat2, lng2);
console.log('sensor three : ',sensor_name3, lat3, lng3);
}
});
});
Hi and welcome on Stack Overflow :)
JavaScript Ajax is asynchronous and you execute console.log() before these variables receive a value.
But in your case you pass to append() which accepts a htmlString, Element, Text, Array or jQuery parameter a assignment of value expression. You don't append a child, but you declared it using append()
You must have to wait for response from server and after use that.
$(function () {
var $sensors = $('#sensors');
$.ajax({
type: 'GET',
url: 'http://127.0.0.1:5000/',
success: function (sensors) {
$.each(sensors, function (i, sensor) {
let sensorInfo = 'sensor #'+i+': '+sensor.name+' '+sensor.lat+' '+sensor.lng;
console.log(sensorInfo);
$sensors.append('<p>'+sensorInfo+'</p>')
});
}
});
});
Greetings, plum!
Sources:
Asynchronous on MDN: https://developer.mozilla.org/en-US/docs/Glossary/Asynchronous
jQuery Docs: https://api.jquery.com/jQuery.get/#jQuery-get-url-data-success-dataType

Javascript access TDs from closest TR. Javascript PHP Session

I am using this snippet: http://bootsnipp.com/snippets/featured/payment-form-with-total-preview
And my problem is on the X click, when removing an element, I would like to access the value of the TDs (Concept, Description, Amount, Status and Date), in order to, after having those values, removing the element from my PHP session array, which is an array of all the payments, so I just would do an unset based on the values I get.
This is what I have done so far:
$(document).on('click', '.input-remove-row', function(){
var tr = $(this).closest('tr');
var tds = tr.children('td');
var txt = $(tds[0]).text()
var txt1 = $(tds[1]).text()
var txt2 = $(tds[2]).text()
document.write (txt1)
tr.fadeOut(200, function(){
tr.remove();
calc_total()
});
});
I have trying printing the value of txt, txt1 and txt2 but I always get the amount, I don't reach the other tds, and they are all supposed to be tds with class input based on the other function.
Another question would be how to handle the session here, but that's not the highest priority issue.
Any idea¿? Thank you in advance.
Edit :
If you want to use php to store session value, then you should use $.ajax:
$(document).on('click', '.input-remove-row', function(){
var tr = $(this).closest('tr');
var tds = tr.children('td');
var txt = $(tds[0]).text()
var txt1 = $(tds[1]).text()
var txt2 = $(tds[2]).text()
var data = {
concept: txt,
description: txt1,
amount: txt2
};
$.ajax("YOUR_PHP_POST_URL", {
type: 'POST',
data: data,
success: function(response) {
//Check if store success
if (POST_SUCCESS) {
// remove tr and calc total here
tr.fadeOut(200, function(){
tr.remove();
calc_total();
});
} else {
//notify store failed...
}
},
});
});
When you want the sessioned data, you can use:
$.ajax("YOUR_PHP_GET_URL", {
success: function(response) {
// convert reposnse to object
// then do something like append this data to table, and calc_total
},
});
Or if you use PHP to create the page, you can directly put those session data on table while rendering.
For more about ajax, go to jquery ajax, and you can also find more details, examples on internet.

Getting and Setting a data attribute in HTML

I have an edit box, defined like this:
<input class="change-handled form-control" type-id="#sub.CategoryTypeId" sub-category-id="#sub.SubCategoryId" data-id="#sub.CategoryBudgetId" style="text-align: right; width: 100%" type="number" value="#(sub.BudgetAmount.HasValue ? sub.BudgetAmount.ToString() : "")" />
In Javascript, I get the data-id value successfully like this:
var dataId = $(this).attr('data-id');
I now need to set it to a different value. I am trying:
$(this).setAttribute("data-id", 5);
But it seems the data-id never gets set to the value I pass. How can I set the data-id value of my editbox?
Full code of the function being used. (Note, no error checking yet):
$('body').on('change', 'input.change-handled', UpdateTotals);
function UpdateTotals() {
var dataId = $(this).attr('data-id');
var categoryId = $(this).attr('sub-category-id');
var value = $(this).val();
var totalExp = 0;
var totalInc = 0;
var $changeInputs = $('input.change-handled');
$changeInputs.each(function (idx, el) {
if ($(el).attr('type-id') == 2) {
totalInc += Number($(el).val());
}
if ($(el).attr('type-id') == 1) {
totalExp += Number($(el).val());
}
});
$(this).val(numberWithCommas(value));
$('#budgettedExpenseValue').text(numberWithCommas(totalExp));
$('#budgettedIncomeValue').text(numberWithCommas(totalInc));
$('#budgettedAvailableValue').text(numberWithCommas(totalInc - totalExp));
$.ajax({
url: '#Url.Action("SaveBudgetValue", "Budget")',
type: "POST",
contentType: "application/json",
data: JSON.stringify({ budgetCategoryId: dataId, catgoryId: categoryId, month: 4, year: 2015, value: value }),
cache: false,
async: true,
success: function (result) {
if (result.Success == 'true') {
$(this).attr("data-id", result.Id);
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
},
error: function () {
alert("Oh no...");
}
});
The code, after an edit box of the class type is edited, sums up all the income boxes (Decorated with a type-id = 1), and updates a field, and all the expense boxes (type-id = 2) and updates a separate field.
It then saves the data with a json call to my controller. If it's a new entry, data-id would have been NULL. The save method returns the primary key of the value saved. That value is displayed in my alert, and is supposed to be assigned to the edit boxe's data-id. But - isn't.
Re your update
The problem is that in the ajax success callback, this doesn't refer to the element anymore.
Two ways to fix that, and a third way that will be available in ES6:
Assign this, or more usefully $(this), to a variable that you use in the success handler (and elsewhere, no need to constantly call $() repeatedly on the same element):
function UpdateTotals() {
var input = $(this); // <========== Save it here
// ...
$.ajax({
// ...
success: function (result) {
// ...
if (result.Success == 'true') {
input.attr("data-id", result.Id); // <========= Use it here
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
}
});
// ...
}
Use Function#bind (an ES5 feature, but it can be shimmed for really old browsers) to make this within the callback the same as this outside it:
function UpdateTotals() {
// ...
$.ajax({
// ...
success: function (result) {
// ...
if (result.Success == 'true') {
$(this).attr("data-id", result.Id);
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
}.bind(this) // <=========== Note
});
// ...
}
In ES6, we'll have arrow functions, which unlike normal functions inherit the this of the context in which they're created. So in ES6, you could do this:
// **ES6 ONLY**
function UpdateTotals() {
// ...
$.ajax({
// ...
success: (result) => { // <==== Arrow function syntax
// ...
if (result.Success == 'true') {
$(this).attr("data-id", result.Id);
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
}
});
// ...
}
I'd lean toward #1, because you're doing a lot of repeated $(this) anyway, so just as well to do var input = $(this); once and then use input throughout.
More about this on my blog:
You must remember this
Original answer pre-update:
Since you're using jQuery, you set an attribute with attr, like this:
$(this).attr("data-id", 5);
Live Example:
var input = $("input");
snippet.log("Before: " + input.attr("data-id"));
input.attr("data-id", 5);
snippet.log("After (jQuery): " + input.attr("data-id"));
snippet.log("After (DOM): " + input[0].getAttribute("data-id"));
snippet.log("Element's HTML (after): " + input[0].outerHTML);
<input class="change-handled form-control" type-id="#sub.CategoryTypeId" sub-category-id="#sub.SubCategoryId" data-id="#sub.CategoryBudgetId" style="text-align: right; width: 100%" type="number" value="#(sub.BudgetAmount.HasValue ? sub.BudgetAmount.ToString() : "")" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Or you can just use the DOM directly, by not wrapping the element in a jQuery wrapper:
this.setAttribute("data-id", 5);
Note that in either case, even though you're giving a number as the value, the value will end up being a string (as attributes only store strings).
You'll get people telling you to use data, but data is not just a way to access data-* attributes, even though many people make that mistake. It might be useful for your end goal, though, depending on what that is. The jQuery data function manages a cache of data that it associates with the element. The values data manages are initialized from data-* attributes, but data never writes to data-* attributes. If you're just trying to update attribute values, use attr. If you're trying to do something more complex and it's not important that the values get written back to the element as attributes, look at the docs for data and see whether it might be useful for you. (For one thing, the values data manages can be types other than strings.)
You are putting your code in the success function where this will be some sort of jQuery ajax object and not an HTML element.
You need to store this in a variable outside the ajax call and then use that variable.
e.g.
var that = this;
$.ajax({
Then:
setAttribute is a DOM method, not a jQuery method.
Either:
$(that).attr("data-id", 5);
or (assuming this is a Element object):
that.setAttribute("data-id", 5);

Javascript - unable to call function from another file

I'm trying to call a function from one file in another js file.
general.js
function delete_post(post_id, post_type, nonce) {
$.post(Ajax.ajaxurl, { action: 'delete_post', post_id: post_id, nonce: nonce, post_type: post_type}, function (data) {
var result = $.parseJSON(data);
if (result.status == 'error') {
$('#post_'+post_id).prepend('<div class="alert alert-danger">' + result.message + '</div>');
}
if (result.status == 'success') {
$('#post_'+post_id).fadeOut(1000, function(){
$(this).remove();
});
}
});
}
details.js
$('body').on('click', '.remove-row', function (e) {
e.preventDefault();
var post_id = $(this).attr('data-target');
var nonce = $(this).attr('data-nonce');
var parent_id = $(this).attr('data-parent');
var post_type = $(this).attr('data-post_type');
bootbox.confirm(Ajax.are_you_sure, function(result) {
if (result) {
delete_post(post_id, post_type, nonce);
}
});
});
On the page they are loaded in the correct order:
<script type='text/javascript' src='http://domain.com/js/general.js?ver=3.9.1'></script>
<script type='text/javascript' src='http://domain.com/js/details.js?ver=3.9.1'></script>
However, when I click on the remove-row button, I get Uncaught ReferenceError: delete_post is not defined.
What am I missing?
That error tells us that you haven't shown all of general.js, and in particular that your function declaration for delete_post is inside another function (one possible example below). So it's not a global.
If you want to make it a global, you can do that by putting this line in general.js:
window.delete_post = delete_post;
The properties of the window object are globals.
In general, I would recommend keeping globals to a minimum, so you might want to have a single global object you use for all your stuff, along these lines:
if (!window.myApp) {
window.myApp = {};
}
window.myApp.delete_post = delete_post;
...and then instead of
delete_post(post_id, post_type, nonce);
...in your other file, use
myApp.delete_post(post_id, post_type, nonce);
When I say it's inside another function, here's one example of that:
$(document).ready(function() {
function delete_post() {
// ...
}
});
Your example may look slightly different, but that's the gist.

Categories

Resources