Uncaught Reference error with JS and AJAX - javascript

This is my td that wrote with JS:
'<td contenteditable="true" onBlur="saveToDatabase(this,s1,' + d.pid + ')" onClick="showEdit(this);">' + d.s1+ '</td>' +
I want to to send saveToDatabase function value to this AJAX code.
function showEdit(editableObj) {
$(editableObj).css("background", "#FFF");
}
function saveToDatabase(editableObj,column ,id) {
$(editableObj).css("background", "#FFF url(loaderIcon.gif) no-repeat right");
$.ajax({
url: "saveedit.php",
type: "POST",
data: 'column=' + column + '&editval=' + editableObj.innerHTML + '&id=' + id,
success: function(data) {
$(editableObj).css("background", "#FDFDFD");
}
});
}
But I get an error:
Uncaught ReferenceError: hashie_sod is not defined
what is the problem ?

It sounds like hashie_sod is the value in your d.pid variable. In which case you need to wrap it in quotes when building your HTML string:
'<td contenteditable="true" onBlur="saveToDatabase(this, s1, \'' + d.pid + '\'")" onClick="showEdit(this);">' + d.s1+ '</td>'
Or better yet, use JavaScript to attach your events:
'<td contenteditable="true" class="content-edit-td" data-s1="' + s1 + '" data-pid="' + d.pid + '">' + d.s1+ '</td>'
$('.content-edit-td').on({
'click': function() {
$(this).css("background", "#FFF");
},
'blur': function() {
$(this).css("background", "#FFF url(loaderIcon.gif) no-repeat right");
$.ajax({
url: "saveedit.php",
type: "POST",
data: 'column=' + $(this).data('s1') + '&editval=' + $(this).html() + '&id=' + $(this).data('pid'),
success: function(data) {
$(this).css("background", "#FDFDFD");
}
});
}
});

Related

How can I generate a dynamic onclick which pass multiple values to a function?

I need to pass multiple values from an onclick attribute to a function. So I need the onclick to be formatted this way onclick='getLine("1","text");'
//Ajax call with dynamic onclick
$.ajax({
url: 'data/tiles-personal.json',
dataType: 'json',
type: 'get',
cache: false,
success: function(pdata) {
$(pdata.tile).each(function(index, value) {
console.log(value.name, value.id, +'States(' + value.states + ')');
if (value.name == "MA Auto (Stand Alone)" || value.name == "USLI Events" || value.name == "USLI Personal Lines") {
document.getElementById("rowP").innerHTML = "<div class='filterrowP' data-state='" + value.states + "'><div class='col-sm-4' style='background-color:#FFFFFF;'>" + "<span class='sm-4-corner'>Coming soon</span>" + "<div name='footprintinfo' class='footprintinfo' style='position:absolute;left:122px;z-index:200;'><a href='##' title='" + value.name + "'><i class='fa fa-info-circle' aria-hidden='true'></i></a>" + "</div><a href='#' onclick='getLine(1," + value.name + ")' class='href-nav'><img src=images/" + value.image + " border='0' class='ind' title='" + value.name + "'/>" + "<div class='tiles-t'>" + value.name + "</div></a></div></div>";
} else {
document.getElementById("rowP").innerHTML = "<div class='filterrowP' data-state='" + value.states + "'><div class='col-sm-4' style='background-color:#FFFFFF;'>" + "<div name='footprintinfo' class='footprintinfo' style='position:absolute;left:122px;z-index:200;'><a href='##' title='" + value.name + "'><i class='fa fa-info-circle' aria-hidden='true'></i></a>" + "</div><a href='#' onclick='getLine(1,none);' class='href-nav'><img src=" + value.image + " border='0' class='ind' title='" + value.name + "' />" + "<div class='tiles-t'>" + value.name + "</div></a></div></div>";
}
});
}
});
//function that receives the onclick values
function getLine(initValue, initTxt) {}
<!-- div that displays the json data -->
<div id="rowP" class="rowP" style="padding-left: 30px;"></div>
Don't use inline event handlers or styling. They are bad practice as they tie the HTML and CSS/JS logic together, which is the opposite of what you want.
Instead, put the unique data in a data attribute on the element, then read it back out in a delegated event handler.
Also note that your code is overwriting innerHTML in every iteration of the loop, so only the last item will be visible. You should look in to appending the new content instead, something like this:
<div id="rowP" class="rowP"></div>
var $row = $('#rowP');
$.ajax({
url: 'data/tiles-personal.json',
dataType: 'json',
type: 'get',
cache: false,
success: function(pdata) {
pdata.tile.forEach(function(tile) {
$row.append(`<div class="filterrowP" data-state="${value.states}"><div class="col-sm-4"><span class="sm-4-corner">Coming soon</span><div name="footprintinfo" class="footprintinfo"><i class="fa fa-info-circle" aria-hidden="true"></i></div><img src="images/${value.image}" border="0| class="ind" title="${value.name}" /><div class="tiles-t">${value.name}</div></div></div>`);
});
}
});
$row.on('click', '.href-nav', function() {
var name = $(this).data('name');
// your logic here...
});
#rowP {
padding-left: 30px;
}
.filterrowP {
background-color: #FFFFFF;
}
.footprintinfo {
position: absolute;
left: 122px;
z-index: 200;
}

jquery ajax nested callbacks

I have nested callabcks but resulted output is not ordered correctly. My ajax results are in ascending orders of id but html generated is random. can someone help me out pls?
var formatedhtml = '';
$.ajax({
type: "POST",
url: BASE_URL + 'index.php/orders/read',
dataType: 'json',
success: function(data) {
$.each(data, function(key, value) {
console.log(value);
getdetails(value['id'], function(output) {
formatedhtml = formatedhtml +
'<div class="col-md-4 col-sm-4 col-lg-3 col-xs-6">' +
' <div class="row">' +
' <div class="orderno">' + value['id'] + '</div>' +
'<div class="tableno">' + value['tableno'] + '</div>' +
'<div class="ordertype">' + value['type'] + '</div>' +
'<div class="timestamp">' + value['created'] + '</div>' +
' </div>' +
'<hr>';
$.each(JSON.parse(output['items']), function(k, val) {
formatedhtml = formatedhtml + '<div class="row">' +
'<div class="quantity">' + val[3] + '</div>' +
'<div class="item">' + '</div>' +
'</div>';
});
formatedhtml = formatedhtml +
'<div class="row">' +
'<div class="notes">' + value['id'] + '</div>' +
'</div>' +
'</div>';
$("#orderlist").html(formatedhtml);
console.log(output);
});
});
}
});
edit:
Here is getdetails function. its an ajax request.
function getdetails(id, callback) {
var result;
$.ajax({
type: "POST",
url: BASE_URL + 'index.php/orders/readdetails',
dataType: 'json',
data: {
id: id,
},
success: function(data) {
callback(data[0]);
}
});
};
There are a lot of ways to achieve this, one is to use a promise and sort by id when all requests are done. Another you could create the template and append the details on callback as each detail request has an id you can define in your template a class like 'id-'+value['id'] and use jquery selector and append detail template.
Another solution would be to create a function loop that calls itself untill orderCount == orderLoaded.
Job is done synchronously (takes more time)
//Mock ajax function
$.ajax = function (param) {
if(param.url.indexOf('readdetails') != -1){
param.success(itemsData);
} else {
param.success(ordersData);
}
};
//Mock data
var ordersData = [
{ id : 1, tableno : 'xyz', type: 'invoice', created: '01/01/2001' },
{ id : 2, tableno : 'xyz', type: 'invoice', created: '01/01/2001' },
{ id : 3, tableno : 'xyz', type: 'invoice', created: '01/01/2001' }
];
var itemsData = [
{ id : 1, orderid: 1, quantity: 5 },
{ id : 2, orderid: 1, quantity: 2 },
{ id : 3, orderid: 1, quantity: 1 }
];
// Globals
var formatedhtml = [];
var orders = [];
var lastOrderLoaded = 0;
var BASE_URL = 'localhost/';
function tpl(order, items) {
var html = '<tr class="col-md-4 col-sm-4 col-lg-3 col-xs-6">' +
' <td class="orderno">' + order['id'] + '</td>' +
'<td class="tableno">' + order['tableno'] + '</td>' +
'<td class="ordertype">' + order['type'] + '</td>' +
'<td class="timestamp">' + order['created'] + '</td>' +
' </tr>';
$.each(items, function(key, item) {
html += '<tr class="row">' +
'<td class="item">item: ' + item.id + '</td>' +
'<td class="quantity">quantity: ' + item.quantity + '</td>' +
'</tr>';
});
html +=
'<tr class="row">' +
'<td class="notes"> notes </td>' +
'<td class="notes"> order id ' + order['id'] + '</td>' +
'</tr>' +
'</tr>';
formatedhtml.push({ id: order.id, html : html });
}
$.ajax({
type: "POST",
url: BASE_URL + 'index.php/orders/read',
dataType: 'json',
success: function(data) {
lastOrderLoaded = 0;
orders = data;
getdetails(orders[0]);
}
});
function getdetails(order) {
$.ajax({
type: "POST",
url: BASE_URL + 'index.php/orders/readdetails',
dataType: 'json',
data: {
id: order.id,
},
success: function(data) {
tpl(order, data);
if(lastOrderLoaded < orders.length - 1){
lastOrderLoaded++;
getdetails(orders[lastOrderLoaded]);
} else {
formatedhtml.forEach(function(element){
$("#orderlist").append(element.html);
}); // end each
}
}
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="orderlist" border="1">
<tr><th>id</th><th>no</th><th>type</th><th>date</th></tr>
</table>
Promise Solution:
Job is done asynchronously (might take less time also bombards the server with many requests at once)
var formatedhtml = [];
function tpl(order, items) {
var html = '<div class="col-md-4 col-sm-4 col-lg-3 col-xs-6">' +
' <div class="row">' +
' <div class="orderno">' + order['id'] + '</div>' +
'<div class="tableno">' + order['tableno'] + '</div>' +
'<div class="ordertype">' + order['type'] + '</div>' +
'<div class="timestamp">' + order['created'] + '</div>' +
' </div>' +
'<hr>';
$.each(JSON.parse(items['items']), function(key, item) {
var html += '<div class="row">' +
'<div class="quantity">' + item[3] + '</div>' +
'<div class="item">' + '</div>' +
'</div>';
});
html +=
'<div class="row">' +
'<div class="notes">' + order['id'] + '</div>' +
'</div>' +
'</div>';
formatedhtml.push({ id: order.id, html : html });
}
$.ajax({
type: "POST",
url: BASE_URL + 'index.php/orders/read',
dataType: 'json',
success: function(data) {
var syncLoad = [];
$.each(data, function(key, value) {
syncLoad.push(getdetails(value, tpl));
});
$.when.apply($, syncLoad).done(function() {
formatedhtml.sort(function(a, b){
return a.id - b.id;
});
formatedhtml.forEach(function(element){
$("#orderlist").append(element.html);
});
});
}
});
function getdetails(order, callback) {
return $.ajax({
type: "POST",
url: BASE_URL + 'index.php/orders/readdetails',
dataType: 'json',
data: {
id: order.id,
},
success: function(data) {
callback(order, data[0]);
}
});
};
Use async:false in your getDetails() ajax call.
function getdetails(id, callback) {
var result;
$.ajax({
type: "POST",
url: BASE_URL + 'index.php/orders/readdetails',
dataType: 'json',
async: false,
data: {
id: id,
},
success: function (data) {
callback(data[0]);
}
});

combine a URL with json value

I want to add end point to an url which would be dynamic.Something like below. But following doesn't work. can someone guide me on this.
(href='http://localhost/redmine/projects/' + value.id)
Complete code is as below.
$.ajax({
dataType: "json",
url: "http://localhost/redmine/projects.json",
//data: $.parseJSON(data),
success: function(results){
$.each(results.projects, function(i,value) {
$('.well').append('<h4 class="h5class">'+ value.name+': '+ '<span class="emtext">' +'('+ value.created_on + ')' +'</span>'+ '</h4>'
+ '<p class="hmpclass">'+ value.summary+ '('+ value.description + ')' +'</p>'
+ '<hr class="hrclass">'
);
});
}
});
You have an error here: ...ojects/'+ value.id'">'+ valu....
It should be: ...ojects/' + value.id + '">'+ valu....

jquery multiselect after change removing selected values

have big problem.
have jquery multiselect plugin from here
$.ajax({
url: 'my url',
type: 'post',
data: {'data': data1, 'data2': 'data2'},
dataType: 'json',
success: function(data){
if(data.length >= 1){
$('#selector').find('option').remove();
$.each(data, function(key, value) {
if ($("#selector option[value='" + value.email + "']").length == 0){
$("#selector").append('<option value="'+ value.email +'" data-id="'+value.id+'" data-name="' + value.name + '" data-surname="' + value.surname + '">'+ value.name + ' ' + value.surname + ' ' + ' (' + value.email + ') sent (' + value.sent + ')' +'</option>').multiselect("destroy").multiselect( { sortable : false } );
}
});
}else{
$('#selector').find('option').remove();
$('#selector').append('').multiselect("destroy").multiselect( { sortable : false } );
}
}
});
and after change (call this function, whitch selecting cantacts from other list) my selected values disapears

Why are functions executed in this order?

Code:
function fillChooseCompInAddDeviceDiv(){
$.ajax({
url: "${pageContext.request.contextPath}/StoreServlet",
type: "get",
data: {ajaxId: "2"},
dataType: "json",
success: function(data) {
$("table#choseComponentAddDeviceDiv").find("td").remove();
for(var i = 0; i<data.length; i++) {
$("table#choseComponentAddDeviceDiv").append("<tr>" + "<td>" + data[i].name + "</td>" + "<td>" + data[i].price + "</td>" + "<td>" + data[i].amount + "</td>" + "<td>" + data[i].description + "</td>" + "<td>" + data[i].categoryName + "</td>" + "<td>" + "<a href='" + data[i].link + "'>" + data[i].link + "</a>" + "</td>" + "<td>" + "<img src = '" + data[i].imagePath + "' />" + "</td>" + "<td>" + "<input type='checkbox' class='checkBoxCol' value='" + data[i].name + "'>" + "</td>" + "</tr>");
}
alert("ALERT 1");
},
error: function(status) {
//Do something
}
});
}
//any edit clicked in eny table
function anyEditOnCLick(buttonId, buttonVal){
window.editIsClicked = true;
$("input.nameInput").attr("readonly", true);
if (buttonId === "device"){
$("#addDeviceDiv").css("visibility", "visible");
window.location.hash = "#addDeviceDiv";
fillChooseCompInAddDeviceDiv();
$.ajax({
url: "${pageContext.request.contextPath}/StoreServlet",
type: "get",
data: {ajaxId: "11", toEdit: buttonVal},
dataType: "json",
success: function(data) {
// puni text area
$("#addDeviceFieldName").val(data.name);
$("#addDeviceFieldDescription").val(data.description);
// cekira odgovarajuce komponente, jedan samo data se ocekuje, ne data[]
//fillChooseCompInAddDeviceDiv();
for (var i = 0; i<data.components.length; i++){
$("table#choseComponentAddDeviceDiv td input").filter(function(){return this.value == data.components[i].name}).attr("checked", true);
}
alert("ALERT 2");
},
error: function(status) {
//Do something
}
});
//name is unique - cannot be changed
$("#addDeviceDiv input#addDeviceFieldName").attr("readonly", true);
} else if (buttonId === "component"){
$("#addComponentDiv").css("visibility", "visible");
window.location.hash = "#addComponentDiv";
fillCategorySelection();
$.ajax({
url: "${pageContext.request.contextPath}/StoreServlet",
type: "get",
data: {ajaxId: "21", toEdit: buttonVal},
dataType: "json",
success: function(data) {
$("#addComponentFieldName").val(data.name);
$("#addComponentFieldPrice").val(data.price);
$("#addComponentFieldAmount").val(data.amount);
$("#addComponentFieldDescription").val(data.description);
$("#addComponentFieldLink").val(data.link);
$("#form#uploadForm #imageFile").attr("value", data.imagePath);
//fillCategorySelection();
$("#addComponentDiv select.categorySelect option").filter(function(){return this.value == data.categoryName}).attr("selected", "selected");
},
error: function(status) {
//Do something
}
});
//name is unique - cannot be changed
$("#addComponentDiv input#addComponentFieldName").attr("readonly", true);
} else if (buttonId === "category"){
$("#addCategoryDiv").css("visibility", "visible");
window.location.hash = "#addCategoryDiv";
fillChoseSubCategoriesinAddCategoriesDiv();
$.ajax({
url: "${pageContext.request.contextPath}/StoreServlet",
type: "get",
data: {ajaxId: "31", toEdit: buttonVal},
dataType: "json",
success: function(data) {
$("#addCategoryFieldName").val(data.name);
$("#addCategoryFieldDescription").val(data.description);
//fillChoseSubCategoriesinAddCategoriesDiv();
for (var i = 0; i<data.subCategories.length; i++){
$("table#choseSubCategoriesinAddCategoriesDiv td input").filter(function(){return this.value == data.subCategories[i].name}).attr("checked", true);
}
},
error: function(status) {
//Do something
}
});
//name is unique - cannot be changed
$("#addCategoryDiv input#addCategoryFieldName").attr("readonly", true);
}
}
Function anyEditOnCLick(arg1, arg2) is event function and is placed in onClick tag of a button.
When I click on this button browser always first shows ALERT 2 message and after that go execute fillChooseCompInAddDeviceDiv() and shows ALERT 1. Can someone explain what is really happend here and how can I "persuade" javascript first execute fillChooseCompInAddDeviceDiv()? Before this, i thought function call provides executing whole function body before resuming execution of outer code.

Categories