Error passing json data through ajax method into DataTable - javascript

Im getting an error in my IDE on the console of Google Chrome that states:
Uncaught TypeError: Cannot read property 'length' of undefined. This error is thrown when dataTables takes the raw json data and attempts to inject it into the table.
// Got the data - add it to the table
for ( i=0 ; i<aData.length ; i++ ) {
_fnAddData( settings, aData[i] );
}
<script>
$(document).ready(function(){
$('#clickMe').click(function(){
$.ajaxPrefilter(function(options, originalOptions, jqHXR ){
options.async = true;
});
$.ajax({
//type: 'GET',
url: 'URL',
dataType:"json",
data: "getAddressResults", //name of json expression
success: function(data){
var jsTable = $('#data').dataTable();
jsTable.fnClearTable();
$.each(data, function(key, value){
var i = this.length;
alert("There are : " + i + " entries."); //shows how many objects are in my json data
jsTable.dataTable().fnAddData([
value[key].childName,
value[key].childNum,
value[key].lineNum,
value[key].parentName,
value[key].parentNum
]);
});
if(data){
var txt = "";
if(res > 0){
for (var i=0;i<data.length;i++){
if (data[i].parentNum && data[i].childNum){
txt += "<tr><td>"+data[i].parentNum+"</td><td>"+data[i].childNum+"</td></tr>"
}
}
if(txt !=""){
$("#data").append(txt).removeClass("hidden");
}
}
}
},
error: function(jqXHR, textStatus, errorThrown){
alert(textStatus + ': ' + errorThrown);
}
});
return false;
});
$('#data').DataTable({
columns:[
{ title: "childName" },
{ title: "childNum" },
{ title: "lineNum" },
{ title: "parentName" },
{ title: "parentNum" }
]
});

Remove that <script> tag, you can't just put an html tag like that in between of a javascript.

Related

Using jQuery .when, How to pass in variable number of function calls?

I have a variable number of URL's that I want to make $.ajax(urlx) to and I don't see any examples of how to pass that to $.when. It does not look like .when takes an array, just a list of parameters.
How can I make this work?
var picturesArray = [];
var urlCount = 2;
$.when(
$.ajax(urls[0]),
$.ajax(urls[1])
).done(function() {
var cntx;
for (cntx = 0; cntx < urlCount; cntx++) {
picturesArray.push(arguments[cntx][0]);
}
});
I did finally get it working. The answer is this, though with a few more details.
var requests = [];
for (i = 0; i < urls.length; i++) {
requests.push(
$.ajax({
urlIndex: i,
url: urls[i],
success: function(data, textStatus) {
jsonResult[this.urlIndex] = {
data: data,
status: textStatus,
error: "",
viewed: false
};
console.log("success:" + new Date().getMilliseconds());
},
error: function(jqXHR, textStatus, errorThrown) {
jsonResult[this.urlIndex] = {
data: {},
status: textStatus,
error: errorThrown,
viewed: false
};
console.log("error:" + new Date().getMilliseconds());
}
})
);
}
$.when.apply(undefined, requests).then(
function() {
callback();
},
function() {
callback();
}
);

javascript works on localhost but fails on hosting server

When i click on add-to-basket button i see an error which appears in my browser console saying :
Here is my basket.js file :
$(document).ready(function() {
initBinds();
function initBinds() {
if ($('.remove_basket').length > 0) {
$('.remove_basket').bind('click', removeFromBasket);
}
if ($('.update_basket').length > 0) {
$('.update_basket').bind('click', updateBasket);
}
if ($('.fld_qty').length > 0) {
$('.fld_qty').bind('keypress', function(e) {
var code = e.keyCode ? e.keyCode : e.which;
if (code == 13) {
updateBasket();
}
});
}
}
function removeFromBasket() {
var item = $(this).attr('rel');
$.ajax({
type: 'POST',
url: '/home/u919084925/public_html/mod/basket_remove.php',
dataType: 'html',
data: ({ id: item }),
success: function() {
refreshBigBasket();
refreshSmallBasket();
},
error: function() {
alert('An error has occurred');
}
});
}
function refreshSmallBasket() {
$.ajax({
url: '/home/u919084925/public_html/mod/basket_small_refresh.php',
dataType: 'json',
success: function(data) {
$.each(data, function(k, v) {
$("#basket_left ." + k + " span").text(v);
});
},
error: function(data) {
alert("An error has occurred");
}
});
}
function refreshBigBasket() {
$.ajax({
url: '/home/u919084925/public_html/mod/basket_view.php',
dataType: 'html',
success: function(data) {
$('#big_basket').html(data);
initBinds();
},
error: function(data) {
alert('An error has occurred');
}
});
}
if ($(".add_to_basket").length > 0) {
$(".add_to_basket").click(function() {
var trigger = $(this);
var param = trigger.attr("rel");
var item = param.split("_");
$.ajax({
type: 'POST',
url: '/home/u919084925/public_html/mod/basket.php',
dataType: 'json',
data: ({ id : item[0], job : item[1] }),
success: function(data) {
var new_id = item[0] + '_' + data.job;
if (data.job != item[1]) {
if (data.job == 0) {
trigger.attr("rel", new_id);
trigger.text("Remove from basket");
trigger.addClass("red");
} else {
trigger.attr("rel", new_id);
trigger.text("Add to basket");
trigger.removeClass("red");
}
refreshSmallBasket();
}
},
error: function(data) {
alert("An error has occurred");
}
});
return false;
});
}
function updateBasket() {
$('#frm_basket :input').each(function() {
var sid = $(this).attr('id').split('-');
var val = $(this).val();
$.ajax({
type: 'POST',
url: '/home/u919084925/public_html/mod/basket_qty.php',
data: ({ id: sid[1], qty: val }),
success: function() {
refreshSmallBasket();
refreshBigBasket();
},
error: function() {
alert('An error has occurred');
}
});
});
}
// proceed to paypal
if ($('.paypal').length > 0) {
$('.paypal').click(function() {
var token = $(this).attr('id');
var image = "<div style=\"text-align:center\">";
image = image + "<img src=\"/images/loadinfo.net.gif\"";
image = image + " alt=\"Proceeding to PayPal\" />";
image = image + "<br />Please wait while we are redirecting you to PayPal...";
image = image + "</div><div id=\"frm_pp\"></div>";
$('#big_basket').fadeOut(200, function() {
$(this).html(image).fadeIn(200, function() {
send2PP(token);
});
});
});
}
function send2PP(token) {
$.ajax({
type: 'POST',
url: '/mod/paypal.php',
data: ({ token : token }),
dataType: 'html',
success: function(data) {
$('#frm_pp').html(data);
// submit form automatically
$('#frm_paypal').submit();
},
error: function() {
alert('An error has occurred');
}
});
});
I tried to resolve it but couldn't find a proper solution.
Help me with this, I cannot understand the cause of this error.
This is mainly due to Rules of Origins (CORS), for some reason the javascript(browser) sees the request as not residing in the same server. And the reason for that, I believe, is because /home/u919084925/public_html/mod/basket.php is not seen as a valid url on the server, it should start with http://{hostname}/{path}.
It looks like your ajax url is totally wrong and the browser interpret that is cross origin ajax request. Please simply check in browser's address bar if your ajax provided urls are valid.

Make $ .ajax consider Response code 40x as success

jQuery executes the function "success" if the HTTP status code is in the range of 200 and 299 or is equal to 304.
However, for example, for the code 401 I need jQuery considers that the Ajax call is successful, and it evaluates the response as JSON and executes the function "success".
The problem is that this behavior is hard-coded in the method "done":
// Determine if successful
isSuccess = status> = 200 && status <300 || === status 304;
I do not really see how to do that.
EDIT:
This is what I have for the moment:
var options = {
url: '',
type: 'POST',
data: {},
success: function(response, status){},
error: function(res, status, error){
notify("Une erreur s'est produite !", "danger");
},
complete: function(res, status){}
};
$.extend(options, opts);
var dataString = '';
$.each(options.data, function(key, value){
dataString += ((dataString.length > 0) ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value)
});
$.ajax({
url: site_url + options.url,
type: options.type,
data: dataString,
dataType: 'json',
statusCode: {
401: function() {
setTimeout(function(){
location.reload();
}, 2000);
}
},
success: function(response, status){
if (response.response.result.status == 'ok'){
options.success(response, status);
} else {
if ('message' in response.response.result){
notify(response.response.result.message, "danger");
} else if (response.response.errors.length > 0) {
notify(response.response.errors[0], "danger");
}
}
},
error: options.error,
complete: options.complete
});
I want the answer to be parsed according to the dataType provided (which is only for the "success" method), and, in the case of a code 401, processing is the same as for the other responses containing the correct JSON code, except for a further instruction.
I think it is a mistake for jQuery not be able to change the codes indicating a request as having failed. The content of the response may be important anyway and require special processing.
For a complete web page, the browser still displays the content returned by the server in case of error.
Instead of trying to override the "success" callback why not just make the function call inside the "error" callback,ofcourse before checking the specific error occurred.
error: function(a, b, c){
if(a.status == 401){
// Your custom function call / code.
}
}
Do you have to handle the status code in the success or error block? How about the complete block? It follows both outcomes..
complete
Type: Function( jqXHR jqXHR, String textStatus )
A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object and a string categorizing the status of the request ("success", "notmodified", "nocontent", "error", "timeout", "abort", or "parsererror"). As of jQuery 1.5, the complete setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event.
Source: http://api.jquery.com/jquery.ajax/
Example:
$.ajax({
url: "http://www.google.com"
}).success(function(){ //--> use .done() instead
//things to do on success
}).error(function(){ //--> use .fail() instead
//things to do on error
}).complete(function( data ) { //--> use .always() instead
switch(data.status){
//your logic here
}
});
Finally, given the need for that to go through the "complete" method, it is necessary to recode the entire automation of jQuery.
So there is no interest in using $ .ajax in this case.
That's why I had to code this replacement function that uses the jQuery syntax:
var altAjax = function(opts){
var options = {
url: '',
type: 'GET',
data: {},
dataType: 'text',
successCodes: [304, 401, 403, 404, 500],
statusCode: {},
success: [],
error: [],
complete: []
};
$.extend(options, opts);
var success = function(data, textStatus, xhr){
if ($.isArray(options.success)){
$.each(options.success, function(index, callback){
callback(data, textStatus, xhr);
});
} else if ($.isFunction(options.success)){
options.success(data, textStatus, xhr);
}
if ($.isFunction(options.statusCode[xhr.status])){
options.statusCode[xhr.status](data, textStatus, xhr);
}
}
var error = function(xhr, textStatus, errorThrown){
if ($.isArray(options.error)){
$.each(options.error, function(index, callback){
callback(xhr, textStatus, errorThrown);
});
} else if ($.isFunction(options.error)){
options.error(xhr, textStatus, errorThrown);
}
if ($.isFunction(options.statusCode[xhr.status])){
options.statusCode[xhr.status](xhr, textStatus, errorThrown);
}
}
var complete = function(xhr, textStatus){
if ($.isArray(options.complete)){
$.each(options.complete, function(index, callback){
callback(xhr, textStatus);
});
} else if ($.isFunction(options.complete)){
options.complete(xhr, textStatus);
}
}
var dataString = '';
$.each(options.data, function(key, value){
dataString += ((dataString.length > 0) ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(($.isArray(value) || $.isPlainObject(value)) ? JSON.stringify(value) : value);
});
var req = new XMLHttpRequest();
var url = options.url;
if (options.type.toUpperCase() != 'POST'){
url += ((url.indexOf('?') > -1) ? '&' : '?') + dataString;
}
req.onload = function(){
var textStatus = 'error';
if ((this.status >= 200 && this.status <= 299) || $.inArray(this.status, options.successCodes) > -1) {
var data;
switch (options.dataType.toLowerCase()) {
case 'json':
try {
data = JSON.parse(this.responseText);
} catch (ex){
error(this, textStatus, ex.name + ': ' + ex.message);
break;
}
textStatus = 'success';
success(data, textStatus, this);
break;
case 'xml':
try {
data = $.parseXML(this.responseText);
} catch (ex){
error(this, textStatus, ex.name + ': ' + ex.message);
break;
}
textStatus = 'success';
success(data, textStatus);
break;
default:
textStatus = 'success';
success(this.responseText, textStatus);
}
} else {
error(this, textStatus, null);
}
complete(this, textStatus);
};
req.open(options.type, url, true);
if (options.type.toUpperCase() == 'POST'){
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(dataString);
} else {
req.send();
}
req = null;
};
Instead of success use the complete function and check the xhr.statusText value
$.ajax('url.json', {
complete:function(result) {
if(/^(2\d\d|304|401)$/.test(result.statusText)) {
success();
} else {
error();
}
}
});
You need to handle the conditions at client side checking the status code. You can fetch the status as below:
success: function(data, textStatus, xhr) {
console.log(xhr.status);
},

jQuery Form Validate not posting when using file upload

I've been using jQuery Validate plugin without problems for a while now, but not that I'm trying to use it with a file upload it does not work.
Im getting no post, and the page just reloads too quickly for me to see the "illegal" error that comes up.
The jQuery is as follows:
_validateModalForm = function(formID, modalShow){
var mesContainer = "#modal-message";
$("#" + formID).validate({
invalidHandler: function () { //display error alert on form submit
EMPGlobal.showAlert(mesContainer, '', 'danger', 'There was an error, please check the form, correct, and try again.' , '', '', '', 'warning');
},
submitHandler: function (form){
var formData = form;
formData = new FormData(formData);
console.log(formData);
$.ajax({
url: 'includes/pages/leads.php?',
//data: $(form).serialize(),
data: formData,
mimeType: "multipart/form-data",
type: "POST",
success: function (result) {
$.each(result, function(item, value){
if( (item == 'Success') || (item == 'Warning') ){
if(item == 'Success'){
var alertType = 'success';
} else {
var alertType = 'danger';
}
modalShow.modal('toggle');
EMPGlobal.showAlert('', '', 'success', value, '', '', '', alertType);
$('#lead-report-range').change(); //Reset the boxes
}
});
},
error: function (jqXHR, textStatus, errorThrown) {
returnMes = $.parseJSON(jqXHR.responseText);
message = 'A ' + jqXHR.status + ' ' + errorThrown + ' error occurred. <br /> <i>Message Details: ' + returnMes + '</i>';
EMPGlobal.showAlert(mesContainer, '', 'danger', message, '', '', '', 'warning', jqXHR.status);
},
});
return false;
}
});
$("#" + formID + " input[required='required']").each(function(){
$(this).rules( "add", {
required: true,
minlength: 2
});
});
};
It validates correctly, but just wont post over Ajax.
Any help on this one would be appreciated. I'm sure its something simple that I am missing.
Update
The error is as follows:
Uncaught TypeError: Illegal invocation
n.param.e # jquery-1.11.0.min.js:4
Wc # jquery-1.11.0.min.js:4
n.param # jquery-1.11.0.min.js:4
n.extend.ajax # jquery-1.11.0.min.js:4
$.validate.submitHandler # leads.js:157
d # VM16566:4(anonymous function) # VM16566:4
n.event.dispatch # jquery-1.11.0.min.js:3
n.event.add.r.handle # jquery-1.11.0.min.js:3
With the help of charlietfl managed to get this working.
_validateModalForm = function(formID, modalShow){
var mesContainer = "#modal-message";
$("#" + formID).validate({
invalidHandler: function () { //display error alert on form submit
EMPGlobal.showAlert(mesContainer, '', 'danger', 'There was an error, please check the form, correct, and try again.' , '', '', '', 'warning');
},
submitHandler: function (form){
var formData = new FormData($(form)[0]);
$.ajax({
url: 'includes/pages/leads.php?',
//data: $(form).serialize(),
data: formData,
type: "POST",
dataType: "json",
cache: false,
contentType: false,
processData: false,
success: function (result) {
$.each(result, function(item, value){
if( (item == 'Success') || (item == 'Warning') ){
if(item == 'Success'){
var alertType = 'success';
} else {
var alertType = 'danger';
}
modalShow.modal('toggle');
EMPGlobal.showAlert('', '', 'success', value, '', '', '', alertType);
$('#lead-report-range').change(); //Reset the boxes
}
});
},
error: function (jqXHR, textStatus, errorThrown) {
returnMes = $.parseJSON(jqXHR.responseText);
message = 'A ' + jqXHR.status + ' ' + errorThrown + ' error occured. <br /> <i>Message Details: ' + returnMes + '</i>';
EMPGlobal.showAlert(mesContainer, '', 'danger', message, '', '', '', 'warning', jqXHR.status);
},
});
return false;
}
});
};

How to display the searched data on the jgrid

this is related to my previous question about jqgrid. im doing now a search button that would search my inputed text from the server and display those data (if there is) in the jqgrid. Now, what i did is i create a global variable that stores the filters. Here's my javascript code for my searching and displaying:
filter = ''; //this is my global variable for storing filters
$('#btnsearchCode').click(function(){
var row_data = '';
var par = {
"SessionID": $.cookie("ID"),
"dataType": "data",
"filters":[{
"name":"code",
"comparison":"starts_with",
"value":$('#searchCode').val(),
}],
"recordLimit":50,
"recordOffset":0,
"rowDataAsObjects":false,
"queryRowCount":true,
"sort_descending_fields":"main_account_group_desc"
}
filter="[{'name':'main_account_group_code','comparison':'starts_with','value':$('#searchCode').val()}]";
$('#list1').setGridParam({
url:'json.php?path=' + encodeURI('data/view') + '&json=' + encodeURI(JSON.stringify(par)),
datatype: Settings.ajaxDataType,
});
$('#list1').trigger('reloadGrid');
$.ajax({
type: 'GET',
url: 'json.php?' + $.param({path:'data/view',json:JSON.stringify(par)}),
dataType: Settings.ajaxDataType,
success: function(data) {
if ('error' in data){
showMessage('ERROR: ' + data["error"]["msg"]);
}
else{
if ( (JSON.stringify(data.result.main.row)) <= 0){
alert('code not found');
}
else{
var root=[];
$.each(data['result']['main']['rowdata'], function(rowIndex, rowDataValue) {
var row = {};
$.each(rowDataValue, function(columnIndex, rowArrayValue) {
var fldName = data['result']['main']['metadata']['fields'][columnIndex].name;
row[fldName] = rowArrayValue;
});
root[rowIndex] = row;
row_data += JSON.stringify(root[rowIndex]) + '\r\n';
});
}
alert(row_data); //this alerts all the data that starts with the inputed text...
}
}
});
}
i observed that the code always enter this (i am planning this code to use with my other tables) so i put the filter here:
$.extend(jQuery.jgrid.defaults, {
datatype: 'json',
serializeGridData: function(postData) {
var jsonParams = {
'SessionID': $.cookie("ID"),
'dataType': 'data',
'filters': filter,
'recordLimit': postData.rows,
'recordOffset': postData.rows * (postData.page - 1),
'rowDataAsObjects': false,
'queryRowCount': true,
'sort_fields': postData.sidx
};
return 'json=' + JSON.stringify(jsonParams);
},
loadError: function(xhr, msg, e) {
showMessage('HTTP error: ' + JSON.stringify(msg) + '.');
},
});
now, my question is, why is it that that it displayed an error message "Server Error: Parameter 'dataType' is not specified"? I already declared dataType in my code like above but it seems that its not reading it. Is there anybody here who can help me in this on how to show the searched data on the grid?(a function is a good help)
I modified your code based on the information from both of your questions. As the result the code will be about the following:
var myGrid = $("#list1");
myGrid.jqGrid({
datatype: 'local',
url: 'json.php',
postData: {
path: 'data/view'
},
jsonReader: {
root: function(obj) {
var root = [], fields;
if (obj.hasOwnProperty('error')) {
alert(obj.error['class'] + ' error: ' + obj.error.msg);
} else {
fields = obj.result.main.metadata.fields;
$.each(obj.result.main.rowdata, function(rowIndex, rowDataValue) {
var row = {};
$.each(rowDataValue, function(columnIndex, rowArrayValue) {
row[fields[columnIndex].name] = rowArrayValue;
});
root.push(row);
});
}
return root;
},
page: "result.main.page",
total: "result.main.pageCount",
records: "result.main.rows",
repeatitems: false,
id: "0"
},
serializeGridData: function(postData) {
var filter = JSON.stringify([
{
name:'main_account_group_code',
comparison:'starts_with',
value:$('#searchCode').val()
}
]);
var jsonParams = {
SessionID: $.cookie("ID"),
dataType: 'data',
filters: filter,
recordLimit: postData.rows,
recordOffset: postData.rows * (postData.page - 1),
rowDataAsObjects: false,
queryRowCount: true,
sort_descending_fields:'main_account_group_desc',
sort_fields: postData.sidx
};
return $.extend({},postData,{json:JSON.stringify(jsonParams)});
},
loadError: function(xhr, msg, e) {
alert('HTTP error: ' + JSON.stringify(msg) + '.');
},
colNames:['Code', 'Description','Type'],
colModel:[
{name:'code'},
{name:'desc'},
{name:'type'}
],
rowNum:10,
viewrecords: true,
rowList:[10,50,100],
pager: '#tblDataPager1',
sortname: 'desc',
sortorder: 'desc',
loadonce:false,
height: 250,
caption: "Main Account"
});
$("#btnsearchCode").click(function() {
myGrid.setGridParam({datatype:'json',page:1}).trigger("reloadGrid");
});
You can see the code live here.
The code uses datatype:'local' at the beginning (at the 4th line), so you will have no requests to the server if the "Search" button is clicked. The serializeGridData the data from the postData parameter of serializeGridData will be combined with the postData parameter of jqGrid (the parameter "&path="+encodeURIComponent('data/view') will be appended). Additionally all standard jqGrid parameters will continue to be sent, and the new json parameter with your custom information will additionally be sent.
By the way, if you want rename some standard parameters used in the URL like the usage of recordLimit instead of rows you can use prmNames parameter in the form.
prmNames: { rows: "recordLimit" }

Categories

Resources