I have a script for show and hide some html content.my code like this
$(".head-text").live('click', function (event) {
var header = $(this);
var listid = header.find('strong').attr("data-id");
var list = "#" + listid;
var ajaxManager = $.manageAjax.create('cacheQueue', {
queue: true,
cacheResponse: false
});
if ($(list).length == 0) {
$("#ajax-loading-01").show();
ajaxManager.add({
type: 'GET', url: '/ajaxhandler', data: { showlist: "1", listid: listid }
, success: function (data) {
header.parent().append($(data).find(list)[0].outerHTML);
header.parent()._removeClass('show').addClass('hide');
}
, complete: function () {
$("#ajax-loading-01").hide();
}
, error: function (err) {
}
});
return false;
}
});
It is nice working in chrome and mozilla, but the outerHTML is not working in IE - header.parent().append($(data).find(list)[0].outerHTML)). How can I resolve this problem?
Related
I am working rails application.i need to get status of the each selected device.I am able to achieve this but after executing i am putting alert "Successfully created execution record".For every mac selection it is showing alert message.I need to give one alert in end of execution.I am calling display_result in call_endpoint method.Since it is an Ajax call,it is giving alert for every execution.i don't how to limit to single alert for this.
function display_result() {
$('#http_status').html("");
$('#http_status').append(result["response"].status);
if (result["response"].status == "404") {
console.log("HTTP 404");
$('#response_div').addClass("bs-callout-warning");
} else if (result["response"].status == "520") {
console.log("HTTP 502");
$('#response_div').addClass("bs-callout-danger");
} else {
console.log("HTTP 200");
$('#response_div').addClass("bs-callout-success");
if (result["response"].status == "200") {
// $('.loader').show();
$('#cover-spin').show();
$.ajax({
method: "GET",
dataType: "text",
url: "create_execution",
data: {
http_status: result["response"].status,
mac_address: mac,
},
success: function (execution_record_id) {
$('#cover-spin').hide();
alert('Successfully created execution record");
}
});
}
function call_endpoint() {
var values = new Array();
webpa = $('#Device-PA').is(":visible");
rpil = $('#Device-SN').is(":visible");
groupselect = $('#Group-Select').is(":visible");
parameter_name = $('#tr_object').val();
if (webpa) {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
} else {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
}
serialnumber = $('#pa_serialnumber').val();
oid = $('#sn_serialnumber').val();
protocol = {
pa: pa,
sn: sn,
}
if (pa) {
for (var i = 0; i < m; i++) {
(function () {
var macAdd = values[i];
$.ajax({
method: "GET",
url: "get_object",
dataType: "json",
data: {
parameter: parameter_name,
mac: macAdd,
protocol: protocol,
serialnumber: serialnumber,
},
success: function (result) {
console.log(result);
NProgress.done();
console.log("result for webpa");
display_result();
},
statusCode: {
404: function () {
console.log("Call failed");
}
}
});
})();
}
}
Below is changed code..
Copy below code as it is.
function display_result(total,current) {
$('#http_status').html("");
$('#http_status').append(result["response"].status);
if (result["response"].status == "404") {
console.log("HTTP 404");
$('#response_div').addClass("bs-callout-warning");
} else if (result["response"].status == "520") {
console.log("HTTP 502");
$('#response_div').addClass("bs-callout-danger");
} else {
console.log("HTTP 200");
$('#response_div').addClass("bs-callout-success");
if (result["response"].status == "200") {
// $('.loader').show();
$('#cover-spin').show();
$.ajax({
method: "GET",
dataType: "text",
url: "create_execution",
data: {
http_status: result["response"].status,
mac_address: mac,
},
success: function (execution_record_id) {
$('#cover-spin').hide();
if(total == current)
{
alert('Successfully created execution record");
}
}
});
}
}
}
function call_endpoint() {
var values = new Array();
webpa = $('#Device-PA').is(":visible");
rpil = $('#Device-SN').is(":visible");
groupselect = $('#Group-Select').is(":visible");
parameter_name = $('#tr_object').val();
if (webpa) {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
} else {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
}
serialnumber = $('#pa_serialnumber').val();
oid = $('#sn_serialnumber').val();
protocol = {
pa: pa,
sn: sn,
}
if (pa) {
for (var i = 1; i <= m; i++) {
(function () {
var macAdd = values[i];
$.ajax({
method: "GET",
url: "get_object",
dataType: "json",
data: {
parameter: parameter_name,
mac: macAdd,
protocol: protocol,
serialnumber: serialnumber,
},
success: function (result) {
console.log(result);
NProgress.done();
console.log("result for webpa");
display_result(m,i);
},
statusCode: {
404: function () {
console.log("Call failed");
}
}
});
})();
}
}
}
result and mac is not defined in display_result function. result appears intended to be the resulting value of jQuery promise object returned from $.ajax(). Am not certain what mac is indented to be.
You can substitute $.when() and $.map() for for loop, return a jQuery promise object from call_endpoint(), include error handling, chain .then() to call_endpoint() call to execute alert() once.
function call_endpoint() {
return $.when.apply($, $.map(values, function(macAdd) {
return $.ajax().then(display_result)
}))
}
callEnpoint()
.then(function() {
alert('Successfully created execution record');
}, function(jqxhr, textStatus, errorThrown) {
console.error(errorThrown)
});
function display_result(reuslt) {
..
if (if (result["response"].status == "200")) {
return $.ajax() // remove `alert()` from `success`
}
return;
}
I have created a jQuery function extending its own object $. This function translate those elements attached to the element this:
$.fn.extend({
translate: function(sourceLang, targetLang) {
if($(this).text().trim().length < 1 || !isNaN(parseInt($(this).text().trim())) || sourceLang == targetLang)
return;
let $function = this;
$($function).each(function() {
let $each = this;
$.ajax({
url: 'https://translate.yandex.net/api/v1.5/tr.json/translate',
method: 'GET',
dataType: 'JSONP',
crossDomain: true,
data: {
key: /* my-secret-key */,
text: $($each).text(),
lang: sourceLang + '-' + targetLang
},
success: function(response) {
try {
if(response.code !== 200)
throw "Response: " + response.code;
$($each).text(response.text[0])
} catch(error) {
console.error('Translation error on element: ', $($function).text());
console.error('Message returned by the server:', error);
}
},
error: function(xhr, status, error) {
console.error('Translation error on element: ', $($function).text());
console.error('Message returned by the server:', xhr.responseText);
}
});
});
}
});
After loading the code I do this:
$(document).ready(function() {
let lang = $('html').attr('lang').split('-')[0];
$('td td:visible').translate(lang, "en");
});
Note: the HTML tag looks like this <html lang="es-ES"> depending on the logged user language.
The issue I have is the table loads after a couple of seconds (since we are not in Production environment they could be more than 30). Therefore the previous code block is not useful.
Note: the <tbody> tag is created when the data is added.
What I have tried is:
1. Create a setInterval() and clearInterval() when the $('td:visible').length is greater than 0:
let iv = setInterval(function() {
let lang = $('html').attr('lang').split('-')[0];
let rows = $('tbody td:visible');
if(rows.length > 0) {
rows.translate(lang, "en");
clearInterval(iv);
}
}, 1000);
2. Set a .delay() before the translation:
let isTranslated = false;
while(!isTranslated) {
let lang = $('html').attr('lang').split('-')[0];
let rows = $('tbody td:visible');
if(rows.length > 0) {
rows.delay(1000).translate(lang, "en");
isTranslated = true;
}
}
The memory consumed by the browser is greater than 200MB. I also tried with $('table').on('DOMSubstreeModified', 'tbody', function() {}) but it didn't work.
So, what approach would you recommend to use this translation plugin on this table after it loads its tbody?
Edit 1:
I have changed my code so I perform less API requests, thanks to the recommendation of #lucifer63:
let $function = this;
let collection = [];
let translation = '';
$(this).each(function() {
collection.push($(this).text());
});
let text = collection.join('::');
$.ajax({
url: 'https://translate.yandex.net/api/v1.5/tr.json/translate',
method: 'GET',
dataType: 'JSONP',
crossDomain: true,
data: {
key: /* my-secret-key */,
text: text,
lang: sourceLang + '-' + targetLang
},
success: function(response) {
try {
if(response.code !== 200) {
throw "Response: " + response.code;
}
translation = response.text[0].split('::');
$($function).each(function() {
$(this).text(translation.shift());
});
} catch(error) {
console.error('Message returned by the server:', error);
}
},
error: function(xhr, status, error) {
console.error('Message returned by the server:', xhr.responseText);
}
});
But still, I need to figure out how to print after data has loaded.
Well... I think I found the answer I was seeking:
$('body').on('DOMNodeInserted', 'table', function() {
$('td:visible').translate('es', 'en');
});
It seems it is working correctly.
I have a function that renders 5 images, and pagination. This function used ajax for getting data.
It works well, but when I using the pagination, I can see the process of 'creating' HTML.
I want to add a loading.gif, until all the HTML finished loading, and show all the results
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) {
isCurrentPage = true;
}
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
} else {
errors += data.error;
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
}
});
}
I saw tutorials about promises and callbacks, but I'm not good at it and I don't know how to rewrite my code for those. Is there another way to solve the issue ?
solution: It may come in handy for other:
function hideLoader() { setTimeout(function () { $('.loader-sm').hide(); }, 750); }
function showLoader() { $('.loader-sm').show(); }
function hideList() { $('#imgList').hide(); }
function showList() { setTimeout(function () { $('#imgList').show(200); }, 750); }
success: function () {
if (data.success) {
//do something
} else {
showList();
hideLoader();
}
},
error: function () {
showList();
hideLoader();
},
complete: function () {
showList();
hideLoader();
}
have a class for show loading image icon and place it in the block itself and hide it once completed. have a look at the below sample. it may helpful to you.
beforeSend: function() {
$('#imgList').addClass('loading');
},
success: function(data) {
$("#imgList").removeClass('loading');
},
error: function(xhr) { // if error occured
$("#imgList").removeClass('loading');
},
complete: function() {
$("#imgList").removeClass('loading');
}
otherwise you can have a loader div block show the block on beforesend() and hide it in success / complete.
You can do like this i am not sure about but it will help you
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
let promise = new Promise(function(resolve, reject) {
//add your code for add loading.gif
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val()); },
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) { isCurrentPage = true; }
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
resolve();
} else {
errors += data.error;
resolve();
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
resolve();
}
});
}
promise.then(
result => alert("done"), // remove loading.gif
);
}
I have a module in a different file which should essentially carry out my ajax requests for me (this is in ajaxCall.js), I am trying to add this module to the global window object so that i can use it in another file called (basket-page.js), but I get an error stating
Uncaught TypeError: Cannot read property 'process' of undefined(…)
AjaxCall.js
"user strict";
window.ajaxCall = window.ajaxCall || {}
var ajaxCall = (function () {
var api = {
process: function (destinationUrl, dataToPost, callbackFunction) {
$.ajax({
url: destinationUrl,
data: dataToPost,
method: "POST",
dataType: "JSON",
success: function (data) {
if (element.length > 0) {
callbackFunction(data, element);
}
},
error: function (req, status, errorObj) {
console.log(status);
}
});
}
}
window.ajaxCall = api;
return api;
})();
basket-page.js
"use strict";
basket = basket || {};
var basket = (function (ajax) {
var api = {
init: function () {
$("#tblBasket").dataTable({
bFilter: false,
pageLength: 10,
paging: true,
autoWidth: true,
columns:
[
{ "orderDataType": "dom-text", type: "string" },
{ "orderDataType": "dom-text-numeric" },
null
],
fixedColumns: true
});
},
removeBasketProductRow: function (data, element) {
if (data === true) {
element.remove();
}
}
};
$("#btnRemoveBasketProduct").click(function() {
var product = $(this).closest("tr");
var productId = product.attr("id");
window.ajaxCall.process("/Products/RemoveBasketProduct", productId, api.removeBasketProductRow);
});
return api;
})(window);
$(document).ready(function () {
basket.init();
});
Remove all the function wrapping. It's unnecessary.
"user strict";
window.ajaxCall = {
process: function (destinationUrl, dataToPost, callbackFunction) {
$.ajax({
url: destinationUrl,
data: dataToPost,
method: "POST",
dataType: "JSON",
success: function (data) {
if (element.length > 0) {
callbackFunction(data, element);
}
},
error: function (req, status, errorObj) {
console.log(status);
}
});
}
}
The issue was making sure i had my other script file loaded already, since this is what adds object to the global window object.
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.