Javascript - unable to call function from another file - javascript

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.

Related

Set AJAX response as javascript variable for reuse [duplicate]

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>

Cannot read property 'row' of undefined

//anything inside 'pagebeforecreate' will execute just before this page is rendered to the user's screen
$(document).on("pagebeforecreate", function () {
printheader(); //print the header first before the user sees his page
});
$(document).ready(function () {
searchfriend();
function searchfriend() {
var url = serverURL() + "/getcategories.php";
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (arr) {
_getCategoryResult(arr);
},
error: function () {
validationMsg();
}
});
}
function _getCategoryResult(arr) {
var t; //declare variable t
//loop for the number of results found by getcategories.php
for (var i = 0; i < arr.length; i++) {
//add a new row
t.row.add([ //error
"<a href='#' class='ui-btn' id='btn" + arr[i].categoryID + "'>Category</a>" //add a new [Category] button
]).draw(false);
//We drew a [View] button. now bind it to some actions
$("#btn" + arr[i].categoryID).bind("click", { id: arr[i].categoryID }, function (event) {
var data = event.data;
showcategory(data.id); //when the user clicks on the [View] button, execute showcategory()
});
}
$("#categoryresult").show(); //show the results in the table searchresult
}
function showcategory(categoryID) {
//alert(categoryID);
window.location = "showuser.html?userid=" + userid;
}
});
There is an error on line 33 which stated:
"Uncaught TypeError: Cannot read property 'row' of undefined"
However, it seems that I have no idea where the error is coming from.
Is there anyway I can solve this problem?
You look like you are using a third-party jQuery plugin, DataTables.
Follow the usage of DataTables.
var t; //declare variable t
should be
var t = $("#categoryresult").DataTable();
The variable t is not an object with a property called row.
Try with var t = { row: [] }
Edit: I apologize. I got confused add with push method.
So, you need an object with a method called add and assign that object to t

jQuery blur based checking and print result to a view in codeigniter

Possibly someone asked question like as my question. But, I can't find any solution.
ProfileEditor.php (controller)
method 1:
public function modify_personal_information() {
$this->data['userinfo'] = $this->personal_information_of_mine($userid);
$this->load->view('layouts/header', $this->data);
$this->load->view('profile/personalinformation', $this->data);
$this->load->view('layouts/footer', $this->data);
}
method 2:
public function check_url_if_exists() {
$newportalurl = $this->uri->segment(2);
$this->results = $this->profile_model->checknewportalurl($newportalurl);
if ($this->results == 1) {
$this->status['status'] = 1;
$this->status['msg'] = 'This name is available. Thanks.';
} else {
$this->status['status'] = 0;
$this->status['msg'] = 'This name is not available. See suggestions.';
}
$this->load->view('profile/layouts/availiability', $this->status);
//or echo json_encode($this->status);
}
profile/personalinformation.php (views)
a form with <div id="urlsuggestions"></div>
profile/layouts/availiability.php (views)
where i am printing the message which i am getting from the check_url() function
ajax.js (ajax)
$('#newportalurl').blur(function() {
var fval = $(this).val();
var ifexists = fval.toLowerCase().replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '');
$.ajax(baseurl + "check/"+ifexists, function(data) {
//i tried following things
//alert(window.location);
//$('#msgbox').html(data.msg).show().addClass('alert-success').delay(2000).fadeOut();
//$('#urlsuggestions').load(window.location + 'modifypersonalinformation #urlsuggestions');
});
});
Now, I am trying to load the message to personalinformation view. What I am doing wrong or what will be the procedure to do it? I actually want to know the process how codeigniter handle them.
Please try like this, im not able to get response from your metod.
$.ajax({
url: "<?= base_url("check/") ?>"+ifexists,
success: function (data) {
$("#urlsuggestions").html(data);// if you want to replace the data in div, use .html()
or if you want to append the data user .append()
}
});

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);

Advice requested - passing variables between functions using json/jquery & ajax

I've looked over a lot of 'similar' q&a threads on SO but to be honest, as I don't have too much of a grip on js programming, I'm finding it difficult to make sense of a lot of the answers (as far as they may apply to my own situation).
The context is this, I have two php scripts one returning a list of customer_ids (json encoded) for a set period and the other returning their preferences for news feeds (json encoded).
I wrote the following, having googled a bit to get a basic understanding of how to setup an ajax function in jQuery:
$('document').ready(function() {
$.ajax({
type:'GET', url: 'cust_selection.php', data: '',
succes:function(cstmrid) {
var clistlen = cstmrid.length;
var i=0;
var cstmr;
for( ;cstmr=cstmrid[i++]; ) {
$('#adminPanel>ul>li').append("<a href='' onclick='alert("+cstmr+")' class='lst_admin basic'>"+cstmr+"</a>"); //alert to be replaced with a function call which passes customerid to the function below.
}
},
dataType:'json'
});
var cstmrid = "483972258"; //hardcoded for testing purposes
$.ajax({
type:'GET', url:'newsfpref.php?', data:'cref='+cstmrid,
success:function(npfdata) {
var item;
var n=0;
for( ;item=npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>"+item+"</td></tr>");
}
},
dataType:'json'
});
});
Now from the first ajax function, I get a list of links which I want to be able to click to launch the second ajax function and pass it the customer id so that it can grab a list of the news sources that they've configured for their pages.
The alert and the hard-coded customer id both suggest that the functions are 'working', but when I try and adjust the first function so that:
...
$('#adminPanel>ul>li').append("<a href='' onclick='getCustomerNP("+cstmr+")' class='lst_admin basic'>"+cstmr+"</a>");
... is calling a modified version of the second function, as below:
...
function getCustomerNP(cstmrid) {
$.ajax({
type:'GET', url:'newsfpref.php?', data:'cref='+cstmrid,
success:function(nprfdata) {
var item;
var n=0;
for( ;item=npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>"+item+"</td></tr>");
}
},
dataType:'json'
});
}
Everything seems to just fail at this point. The second function doesn't seem to 'receive' the variable and I'm not sure if it's something elementary that I've overlooked (like some muddled up " and ' placements) or if what I am trying to accomplish is actually not the way jQuery ajax functions interact with each other.
As you can see, I've cannibalised bits of code and ideas from many SO q&a threads, but copying without much of an understanding makes for a frustratingly dependent life.
I would appreciate as much - expansive - comment as you can provide, as well as a solution or two (naturally).
EDIT: Not to confuse anyone further, I've been modifying the above and correcting my (many) errors and typos along the way. At present, the code looks like below:
$('document').ready(function () {
$.ajax({
type: 'GET', url: 'cust_selection.php', data: '',
succes: function (cstmrid) {
var clistlen = cstmrid.length;
var i = 0;
var cstmr;
for (; cstmr = cstmrid[i++]; ) {
var a = $("<a href='' class='lst_admin basic'>" + cstmr + "</a>").click(function () {
getCustomerNP(cstmr)
})
$('#adminPanel>ul>li').append(a); //alert to be replaced with a function call which passes customerid to the function below.
}
},
dataType: 'json'
});
function getCustomerNP(cstmr) {
alert(cstmr);
}
});
You've got a typo in the $.ajax() success function within getCustomerNP(). The function declaration:
success:function(nprfdata) {
... has a parameter nprfdata, but then within the function you use npfdata (missing the r).
Also this code:
var item;
var n=0;
for( ;item=npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>"+item+"</td></tr>");
}
...declares and sets variable news that you never use. And it doesn't seem right to increment n in the for test expression but then use n within the loop. You never set item to anything but you use it in your .append().
(Note also that JS doesn't have block scope, only function scope, so declaring variables inside an if or for loop doesn't limit them to that if or for block.)
I would not create inline onclick handlers like that. I'd probably do something more like this:
$('#adminPanel>ul>li').append("<a href='' data-cstmr='"+cstmr+"' class='lst_admin basic'>"+cstmr+"</a>");
...and then within the document ready setup a delegated event handler to catch the clicks on those anchors:
$('#adminPanel>ul>li').on('click', 'a.lst_admin', function() {
$.ajax({
type:'GET', url:'newsfpref.php?', data:'cref='+ $(this).attr('data-cstmr'),
success:function(npfdata) {
var item,
n=0,
// cache the jQuery object rather than reselecting on every iteration
$table = $('#adminMain>table>tbody');
// increment n only after the current iteration of the loop
for( ;item=npfdata[n]; n++) {
// change to use item
$table.append("<tr><td>"+item.nsource+"</td></tr>");
}
},
dataType:'json'
});
});
As you append your like with <a href='' onclick='getCustomerNP("+cstmr+")', Make sure you can access the function getCustomerNP.
Try to define getCustomerNP as
window.getCustomerNP = function(cstmrid) {
...
If you defined it in the $(document).ready(function(){ ... }) block, try this
$('document').ready(function () {
$.ajax({
type: 'GET', url: 'cust_selection.php', data: '',
succes: function (cstmrid) {
var clistlen = cstmrid.length;
var i = 0;
var cstmr;
for (; cstmr = cstmrid[i++]; ) {
var a = $("<a href='' class='lst_admin basic'>" + cstmr + "</a>").click(function () {
getCustomerNP(cstmr)
})
$('#adminPanel>ul>li').append(a); //alert to be replaced with a function call which passes customerid to the function below.
}
},
dataType: 'json'
});
function getCustomerNP(cstmrid) {
$.ajax({
type: 'GET', url: 'newsfpref.php?', data: 'cref=' + cstmrid,
success: function (nprfdata) {
var item;
var n = 0;
for (; item = npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>" + item + "</td></tr>");
}
},
dataType: 'json'
});
}
});

Categories

Resources