variables showing as undefined in firebug when they are defined - javascript

here is my site http://iadprint.com/products?product=Business%20Card
when i select a value for quantity a price is supposed to show in the pricing div on the top right.
this used to work but for some reason today in firebug under dom i can see that a few variables show undefined. when i do the ajax call iadprint.com/ajax.php?id=1 the data shows correctly and the variables in the js are all defined. what can be wrong? here are the variables that i am seeing undefined.
woCoating_price
woColor_price
woDesign_price
woJob_Name_price
woPDF_Proof_price
woQuantity_price
woRound_Corners_price
woTurnaround_price

I replaced your $.get() call with a full $.ajax() call that includes an error: callback.
The result is that you're getting a parse error because your JSON response is invalid.
"parsererror" "Invalid JSON: {"price":"15.00"}<br/>"
You need to get rid of that <br/> tag.
If this isn't it, then you'll need to provide specific detail on how to reproduce the problem, and in which part of your code you expect to see a defined value.
EDIT: Here's the change handler I used after removing yours:
$("#Quantity").change(function () {
hash = $("#Quantity").val();
console.log('hash',hash);
$.ajax({
url:"ajax.php",
data: { id: hash },
dataType:'json',
success:function (out,b,c) {
woQuantity_price = out.price;
displayPrice();
console.log(out,woQuantity_price,b,c);
},
error:function(a,b,c){
console.log('error:',a,b,c);
}
});
});

Related

PHP variable added to page not populated - getting undefined in Javascript function call

I am having a bit of trouble, and i think my syntax and structure is correct but for some reason the function is failing.
products.php page
i have this function at the bottom of the page which takes the value of $child and adds it to the page, where it gets passed to the Javascript function get_child_options:
jQuery(document).ready(function(){
get_child_options(<?=$child;?>);
});
The function get_child_options is added by my footer.php page
footer.php
function get_child_options(selected){
if(typeof selected === 'undefined'){
var selected = '';
}
var parentID = jQuery('#parent').val();
$.ajax({
url: '/admin/parsers/child_categories.php',
type: 'POST',
data: {parentID: parentID, selected: selected},
success: function (data){
jQuery('#child').html(data);
},
error: function(){alert("Something went wrong with the child options.")},
});
}
jQuery('select[name="parent"]').change(get_child_options);
The error when i load products.php is get_child_options is not declared
I have had a look online and via this forumn and i think the makeup of my function within my products.php page is correct, i just don't understand why its not recognising the function is declared within my footer.php and processing the function.
To add, i have tried this within the function on my products.php page but i got rid of the undefined error but the function didnt pass any data to my get_child_options function.
jQuery(document).ready(function(){
function getchild(child){
var child = <?=$child;?>
get_child_options(child);
}
});
If anyone can help, that would be great and i can't think of what i am doing wrong. TIA
I have reviewed How can I call PHP functions by JavaScript? and feel my situation is different to theres.
I found the issue and it was that my parsers file couldn't see my authentication file to get the function. Once i had add the correct path to the file it all worked.

JSON.parse not working with JSON string returned from an AJAX call

I have a piece of JavaScript that gets data from a backend with an ajax call. There is a JSON string returned and I cannot work out why the JSON.parse is not working.
Here is my code
var success_get = (jQuery).ajax({
url: "<?php echo base_path(); ?>reservation/success_get",
method: "GET",
async: "true"
});
In Firefox I look at the console and I see the JSON returned for success_get is
{"Reservations":[{"Id":"415b68e9-1209-4ca9-9f6b-47116ced1769","ExtraDuration":0,"TotalDuration":1,"CreationTime":"2016-02-08T00:22:59+11:00","ExpiryTime":"2016-02-08T00:32:28+11:00","Sender":{"ReturnOption":"Dispose","ReturnAddress":null,"Id":"044bf5b5-95cd-44d1-a22a-8070b45a26ba","FirstName":"Test","LastName":"User","Email":"web#tz.net","Phone":"85112366"},"Recipient":{"Id":"b53ad6ac-9750-44c8-9bdd-581e89d3be93","FirstName":"Test","LastName":"User","Email":"test#test.com","Phone":"12345678"},"KioskCode":"Hm1","LockerSize":"Small","LockerNumber":"I5","Total":4.5}],"TotalAmount":4.5,"Sender":{"ReturnOption":"Dispose","ReturnAddress":null,"Id":"044bf5b5-95cd-44d1-a22a-8070b45a26ba","FirstName":"Test","LastName":"User","Email":"web#tz.net","Phone":"85112366"},"NumberOfHoursForDropOff":47}
And that looks like valid JSON as far as I can tell
I am then doing the following
success_get.done(function( success ) {
object_rsuccess = JSON.parse(success);
console.log(object_rsuccess);
});
In Firefox I get the error
ReferenceError: object_rsuccess is not defined
However in the console.log I am seeing
Object { Reservations=[1], TotalAmount=4.5, Sender={...}, more...}
And when I expand the sections in braces I am seeing the data I would expect to see.
I would have thought that I could see the variables, eg TotalAmount by doing the following
var totalamount = object_rsuccess.TotalAmount;
But this will not work while I am getting the error for object_rsuccess not defined.
Am I missing something or simply making a silly mistake?
Wrap your code which will use the object_rsuccess in a function:
var theFunctionToBeCalled = function(obj){
var totalamount = obj.TotalAmount;
console.log(totalamount);
};
Then call it within the .done():
success_get.done(function(success) {
var object_rsuccess = JSON.parse(success);
console.log(object_rsuccess);
theFunctionToBeCalled(object_rsuccess);
});
Your AJAX settings makes the function async, which means the rest of your code continues to be executed and even when you define object_rsuccess globally, it will most probably not be available for use when you need it.
Alternative to my suggestion, based on what feels comfortable to you, you can put everything using object_rsuccess within the .done() or change async:true to async:false.

Can't make DataTables work by using jQuery .post()

I am working on a form where a uses chooses a date range in order to display information by using DataTables.
When the user clicks on the button, the dates are sent through jQuery .post() function and it retrieves the info as expected.
Here is the piece of the code related to it:
//Sending the dates range
$.post(url_route, datos, function(data,status){
if(status=='success'){
var response = jQuery.parseJSON(data);
//checking if data were found
if(response.list_events.length === 0){
console.log('No data available');
}
else{
//Let us display the info with DataTables inside div #list_events and
//table #table_id
$('#list_events').html('<table class="table table-striped table-hover" id="table_id"></table>');
$('#list_events table').append('<thead><tr><th>Event</th><th>Type</th><th>Attendance</th><th>Coordinators</th><th>Participants</th><th>Institutes</th><th>Talks</th></tr></thead><tbody></tbody>');
//retrieving the info for each row and append it to the table:
$.each(response.list_events,function(i,item)
{
$('#list_events').find('tbody').append('<tr>');
$('#list_events').find('tbody').append('<td>'+item.Event+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Type+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Attendance+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Coordinator+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Participant+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Institute+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Talk+'</td>');
});//end of each
//initializing DataTables
var table = $('#table_id').DataTable();
}//end of else (info found)
}//end of if success
}//end of post()
So far, the info is displayed in the DataTables but it is not totally working, since only the information is displayed. The DataTables search, next, and previous buttons, as well as the number of results dropdown menu are not shown.
In the console.log I get the following error:
Uncaught TypeError: Cannot read property 'length' of undefined
Any ideas? Can anyone shed some light on this?
Solved
The problem was with the append function.
If I type just one append with only the <tr> like this:
$('#list_events').find('tbody').append('<tr>');
The result in HTML is <tr></tr> That is to say, the tag is closed automatically ... no matter what. So, the solution was to put all the appends in one line like the following:
$('#list_events').find('tbody').append('<tr><td>'+item.Event+'</td><td>'+item.Type+'</td><td>'+item.Attendance+'</td><td>'+item.Coordinator+'</td><td>'+item.Participant+'</td><td>'+item.Institute+'</td><td>'+item.Talk+'</td></tr>');
And that was it ☺
My first thought is that perhaps "response.list_events" is undefined. Certainly your error:
"Uncaught TypeError: Cannot read property 'length' of undefined"
seems to imply that.
My second thought is that I have recently done something similar where I had trouble with the .post method, and found success with the .ajax method.
Try something along these lines:
$.ajax({
type: "POST",
url: url_route,
data: datos,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(returned_from_server){
// your function here
}
});
My third thought is that I don't see where you put your closing row tags.
$.each(response.list_events,function(i,item)
{
$('#list_events').find('tbody').append('<tr>');
$('#list_events').find('tbody').append('<td>'+item.Event+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Type+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Attendance+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Coordinator+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Participant+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Institute+'</td>');
$('#list_events').find('tbody').append('<td>'+item.Talk+'</td>');
$('#list_events').find('tbody').append('</tr>'); // <--- I believe you might be missing this!!
});//end of each
Hopefully this was some help.
If you are using a remote source for your data, it is far more elegant and efficient to let DataTables itself render the data for you.
In your example, you fetch the data, build the table, and then turn it into a "DataTable". If it meets the requirements and gets the job done, you've written perfectly fine code and you should read this answer no more!
But DataTables itself is awfully smart about rendering data detached from the DOM and then slotting it all in place. You get the benefit of more efficient updates while simultaneously having cleaner code.
Here's a basic example. Without testing it in your environment, I can't say for sure it will do your job, but I think it should:
var myTable = $('#table_id').DataTable( {
"ajax": {
"url": url_route,
"data": function(customData) {
customData.datos = datos // need some way to have access to datos
}
}
});
And then on click, if you want to retrieve newer data based on whatever has changed (the date range?) you just have to redraw.
myTable.draw();
I can imagine a few ways to get datos in there-- wrap it up in a function that accepts and uses datos. Declare a namespaced or otherwise quasi-global (or actually global if you're that guy!) variable that myTable would have access to at any given point in time... or even just destroy the current table and call the whole DataTable() on it again.

Function which exists is listed as "undefined"

I don't know exactly why or how this is happening (though if someone has any information as to why or how, it would be greatly appreciated if it was posted here).
My function is supposed to just make a simple ajax call to a specified file, which is then supposed to process that call.
function processLog(process, ajaxData, url) {
switch(process) {
case 'send':
$.post(url, {clientData : ajaxData, type : process},
function(data){
writeLog(data);
}
);
break;
case 'retrieve':
$.post(url, {clientData : ajaxData, type : process},
function(data){
retrieveChatroomData(data);
}
);
break;
}
}
Basically, the function receives three params: process, ajaxData, url. The process is supposed to be either of the value send or retrieve. If it's value is send, it simply writes out the data to the log. If it's retrieve, it retrieves the entire data sent before in the window and posts it for all to see. If anyone needs to see anymore code, I'll happily post, just let me know :).
The main issue is that when I click the following button:
<input type="button" value="send" id="chatroom_send" onclick="processLog('send', $('textarea.chatroom_textarea').value, 'chatroom.base.php');" />
I get a "processLog" is undefined error in the Firebug console.
What am I doing wrong?
Your code may look like this:
$(function() {
function processLog(/* ... */) {
// ...
}
});
Wrapping code in a ready handler like that is needed for some things, but it will pull processLog out of the global scope. Either move it out of the ready handler or add this somewhere in the ready handler to export it to the global scope:
window.processLog=processLog;

prevent jquery ajax to execute javascript from script or html response

According to documentation:
If html is specified, any embedded JavaScript inside the retrieved
data is executed before the HTML is returned as a string. Similarly,
script will execute the JavaScript that is pulled back from the
server, then return nothing.
How to prevent this?
I have js that shall modify the content that is obtained through ajax. Executing it before the html is returned makes no sense as it does not have content to work on (at least in my case).
my code:
function do_ajax(url) {
$.ajax({
cache: false,
url : url,
success: function(response, status, xhr) {
var ct = xhr.getResponseHeader("content-type") || "";
if (ct.indexOf('script') > -1) {
try {
eval(response);
}
catch(error) {}
} else {
var edit_dialog = $('<div class="edit_dialog" style="display:hidden"></div>').appendTo('body');
edit_dialog.html(response);
edit_dialog.dialog({ modal:true, close: function(event, ui) { $(this).dialog('destroy').remove(); } });
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
the script received by ajax is executed twice. First by me in the eval(response), then jquery execute it again (as described in the documentation)
Lee's answer already adequately addresses the case of HTML responses - scripts embedded in these are not in fact executed automatically unless you add the HTML to the DOM, contrary to the erroneous documentation you quoted.
That leaves the other case asked about in your question title - preventing script responses from being executed automatically when received. You can do this easily using the dataType setting.
$.ajax('myscript.js', {
dataType: 'text',
success: function (response) {
// Do something with the response
}
})
Setting dataType to 'text' will cause jQuery to disregard the Content-Type header returned from the server and treat the response like plain text, thus preventing the default behaviour for JavaScript responses (which is to execute them). From the (recently corrected) docs:
The type of pre-processing depends by default upon the Content-Type of the response, but can be set explicitly using the dataType option. If the dataType option is provided, the Content-Type header of the response will be disregarded.
...
If text or html is specified, no pre-processing occurs. The data is simply passed on to the success handler, and made available through the responseText property of the jqXHR object.
jQuery.ajax does not evaluate scripts on return when requesting HTML. The passage you quoted in the question was in fact a long-standing error in the documentation, fixed as of April 2014. The new docs have this to say (emphasis mine):
"html": Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
...
If text or html is specified, no pre-processing occurs. The data is simply passed on to the success handler, and made available through the responseText property of the jqXHR object.
The scripts are evaluated in this case when you call
edit_dialog.html(response);
If you don't want to evaluate the scripts before inserting your response in to the DOM, you should be able to do something like:
edit_dialog.html($($.parseHTML(response)));
parseHTML is the key in that by default it removes script tags. However, be aware that parseHTML is NOT XXS safe and if your source is unknown this is still a security concern.
The documentation states that any embedded Javascript inside the retrieved data will be executed before the HTML is returned as a string. If you want to then alter whatever you have retrieved using your ajax call, you can do so within the succes property:
$.ajax({
url: "example.html",
type: "GET",
dataType: "html",
succes: function(data){
// Example: alert(data);
// Do whatever you want with the returned data using JS or jQuery methods
}
});
That's one of the really annoying things about jQuery that it executes javascript on response.
Other frameworks like MooTools disable script execution from responses unless you specifically set that you want them executed which is a much better approach.
The only way I could figure to prevent scripts being executed is to add a custom dataFilter
Its easy enough but I think it should be default and an ajax option to enable script execution if you want it (I've never had a use for it and other frameworks disable by default for security etc.)
Example
$.ajax('uri',{
dataFilter: function(data, type)
{
type = type || 'text';
if(type=='html'||type=='text'){
/*return data.replace(/<script.*>.*?<\/script>/gi, '');*/
return data.replace(/<script.*?>([\w\W\d\D\s\S\0\n\f\r\t\v\b\B]*?)<\/script>/gi, '');
}
return data;
}
, success: function(data)
{
// whatever
}
});
** UPDATED **
Needs that crazy regex to cover more script tag instances
NOTE
if dataType hasnt been set in options it will be undefined in dataFilter so I just default it to text for the filter - if you remove that line then it will only work if dataType is explicitly set.

Categories

Resources