Ajax success function to fire another ajax function whilst iterating through loop - javascript

I have the following js/jquery code:
var trigger = $('#loadTableData');
var wrapperClass = 'tableAccordionWrapper';
var url = 'data/tableData.json';
var template = 'includes/tableInput.html';
var parentWrapper = $('#selectedTables .sub-content .input-controls');
var href;
var intID;
var items;
var i;
// retrieve node data send from exteral source
addExternalTableInput = function(){
$('.tableAccordionWrapper').remove();
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success:function(data){
items = data.items
for(i in items){ // this loops 3 times
addExternalTemplate();
}
},
error:function(status){
console.log(status, "Something went wrong");
},
complete:function(){
}
});
}
// append table input to document
addExternalTemplate = function(){
var wrapper;
$.ajax({
type: 'GET',
url: template,
dataType: 'html',
success:function(data){
intID = i;
wrapper = $('<li/>');
wrapper.addClass(wrapperClass);
wrapper.attr('data-id','table-' +intID);
href = $('<a href="#"/>');
wrapper.append(href);
wrapper.append(data).insertBefore(parentWrapper);
var anchor = wrapper.find('> a');
anchor.html(items[intID].tableName); // this returns 'DB_SOURCE_3' for all 3 templates added to the DOM
},
error:function(status){
console.log(status, "Something went wrong");
},
complete:function(){
}
});
}
The concept is that I am using a small json file to run another ajax request. The length of the data in the json file determines how many times the consecutive function should be fired.
The json contains very basic data, but as I loop through it I want the second ajax function to append a template of html to the document (at which point I want to be able to run other functions). One part of data from the json file needs to be injected into the template as it is iterating through the loop.
It appears that the loop works in that in this example the html template gets appended to the dom 3 times, but it passes the last table name in the json to each template that is added to the dom. The second function appears to run after the loop has finished.
Example JSON:
{
"items":[
{
"tableName": "DB_SOURCE_1",
"tableID" : "14739",
"tableDescription" : "Main customer table"
},
{
"tableName": "DB_SOURCE_2",
"tableID" : "184889",
"tableDescription" : "Partitions table"
},
{
"tableName": "DB_SOURCE_3",
"tableID" : "9441093",
"tableDescription" : "Loans Table"
}
]
}
I have tried passing the function in the ajax complete function.
I have also tried to trigger the second ajax function inside the first ajax success function like so:
addExternalTableInput = function(){
$('.tableAccordionWrapper').remove();
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success:function(data){
items = data.items
for(i in items){
$.ajax({
type: 'GET',
url: template,
dataType: 'html',
success:function(data){
intID = i;
wrapper = $('<li/>');
wrapper.addClass(wrapperClass);
wrapper.attr('data-id','table-' +intID);
href = $('<a href="#"/>');
wrapper.append(href);
wrapper.append(data).insertBefore(parentWrapper);
var anchor = wrapper.find('> a');
anchor.html(items[intID].tableName);
},
error:function(status){
console.log(status, "Something went wrong");
},
complete:function(){
}
});
}
},
But everything I have tried seems to return the same results.

The code has been rewritten somewhat, but here is what I am doing.
var templateData;
addExternalTableInput = function(){
$('.tableAccordionWrapper').remove();
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success:function(data){
var items = data.items;
for(var i in items){
addExternalTemplate(items[i], i); // pass parameters to this function
}
},
error:function(status){
// etc.
}
});
}
addExternalTemplate = function(item, intID){ // add parameters to our function so we can access the same data
var wrapper;
// load template data once
if(!templateData){ // only run this function if !templateData (should only run once).
$.ajax({
type: 'GET',
url: template,
dataType: 'html',
async: false, // wait until we have a response before progressing
success:function(data){
templateData = data;
},
error:function(status){
console.log(status, "Something went wrong");
}
});
}
// append templateData to the dom
if(templateData){
var href = $('<a href="#"/>');
var tableNameInput = wrapper.find('[name="tables"]');
tableNameInput.val(item.tableName);
// etc
}
// update for, id and name attributes etc.
updateInputAttributes = function(){
// do other stuff to each instance of the template
}();
}
I have moved alot of the global variables out and instead I am using function parameters.
I am only calling the html template once, but for each iteration of the loop I can run functions to update certain atrributes in that instance of the template as well as match items in the json to items in the template.

Related

Unexpected characters in image url in ajax response Javascript

In My Codeigniter web application I'm using an ajax function to get some data from the database inorder to show it in the view.The data from database contains an image url and other fields.
My problem is that when I get the data in ajax success function, the image url looks like this:
<button id='product-1301' type='button' value=1301 class='blue' ><i><img src='assets\/uploads\/thumbs\/default.png'></button>
Since the url contains these characters \ my view is not rendering properly. I tried using stripslash function to remove this. But didn't work. I didn't know where am going wrong.
my ajax function
$.ajax({
type: "get",
url: "index.php?module=pos&view=ajaxproducts1",
data: {category_id: cat_id, per_page: p_page},
dataType: "html",
success: function(data) {
var x= data;
alert(x);
if(data!=1)
{
$('#proajax').empty();
var newPrs = $('<div></div>');
newPrs.html(data);
newPrs.appendTo("#proajax");
//$('#gmail_loading').hide();
}
else
{
bootbox.alert('Product is Not Available in this Category!');
$('#gmail_loading').hide();
}
}
});
Controller
function ajaxproducts1()
{
$mn;$data1;
$img="assets/uploads/thumbs/default.png"; //this is my image path, when this comes in ajax success,\ character adds
$img=str_replace('\"', '', $img);
if($this->input->get('category_id')) { $category_id = $this->input->get('category_id'); }
if($this->input->get('per_page')) { $per_page = $this->input->get('per_page'); }
if($item = $this->pos_model->getProductsByCategory($category_id,$per_page))
{
foreach ($item as $i)
{
$button="<button id='product-".$i->id."' type='button' value=".$i->id." class='blue' ><i><img src='".$img."'><span><span>".$i->name;
$mn=$mn.$button;
}
$data1=$mn;
}
else
{
$data1=1;
}
echo json_encode($data1);
}
Can anyone help me with this ?
Try this:
// use an array to gather up all the values
// call encodeURIComponent() on the variables before adding them
// join them all together and pass them as "data"
var tempVars=['module=pos&view=ajaxproducts1'];
tempVars.push('category_id='+encodeURIComponent( cat_id ));
tempVars.push('userInfo='+encodeURIComponent( p_page ));
var sendVars=tempVars.join('&');
$.ajax({
type: "get",
url: "index.php",
data: sendVars,
dataType: "text",
success: function(data) {
var x = data;
alert(x);
if (data != 1) {
$('#proajax').empty();
var newPrs = $('<div></div>');
newPrs.html(data);
newPrs.appendTo("#proajax");
//$('#gmail_loading').hide();
} else {
bootbox.alert('Product is Not Available in this Category!');
$('#gmail_loading').hide();
}
}
});
My issue was solved by using jQuery.parseJSON function.

How to check json response taken longer than 5 seconds?

Below is the sample code of my function. in the for loop one by one product id is pass in the ajax function and get product price from the php file as response and write it and html.
for(var i=0; i < data.products.length; i++){
var doc = data.products[i];
$.ajax({ // ajax call starts
url: 'product.php',
data: { product_id: doc.id },
dataType: 'json',
success: function(data)
{
document.getElementById('price_price'+data.product_id+'').innerHTML = data.products_price;
}
});
}
I have found that sometimes it takes a more time for price to display. i want to check which record is taking time to load. how can check to detect when it takes longer than 5 seconds for the price to load?
Something like this....
var ajaxTime= new Date().getTime();
$.ajax({
type: "POST",
url: "some.php",
}).done(function () {
var totalTime = new Date().getTime()-ajaxTime;
// Here I want to get the how long it took to load some.php and use it further
});
Also, by the way, if you want to prevent sending (i+1) request, before (i) is completed, you'd maybe want to use syncronous ajax request instead of async.
Try to log timestamp beforesend and success or error
$.ajax({ // ajax call starts
url: 'product.php',
data: { product_id: doc.id },
dataType: 'json',
beforeSend: function() {
console.log(new Date().getSeconds());
}
success: function(data)
{
console.log(new Date().getSeconds());
document.getElementById('price_price'+data.product_id+'').innerHTML = data.products_price;
}
});
Use setTimeout, like this:
var timeoutTimer = setTimeout(function() {
// time out!!!.
}, 5000);
$.ajax({ // ajax call starts
url : 'product.php',
data : {
product_id : doc.id
},
dataType : 'json',
success : function(data) {
document.getElementById('price_price' + data.product_id + '').innerHTML = data.products_price;
},
complete : function() {
//it's back
clearTimeout(timeoutTimer);
}
});

How to unbind or turn off all jquery function?

I have constructed an app with push state. Everything is working fine. However in some instances my jquery function are fireing multiple times. That is because when I call push state I bind the particular js file for each page I call. Which means that the same js functions are binded many times to the html while I surf in my page.
Tip: I am using documen.on in my jquery funciton because I need my function to get bound to the dynamical printed HTML through Ajax.
I tried to use off in the push state before printing with no success!
Here is my code:
var requests = [];
function replacePage(url) {
var loading = '<div class="push-load"></div>'
$('.content').fadeOut(200);
$('.container').append(loading);
$.each( requests, function( i, v ){
v.abort();
});
requests.push( $.ajax({
type: "GET",
url: url,
dataType: "html",
success: function(data){
var dom = $(data);
//var title = dom.filter('title').text();
var html = dom.find('.content').html();
//alert(html);
//alert("OK");
//$('title').text(title);
$('a').off();
$('.push-load').remove();
$('.content').html(html).fadeIn(200);
//console.log(data);
$('.page-loader').hide();
$('.load-a').fadeIn(300);
}
})
);
}
$(window).bind('popstate', function(){
replacePage(location.pathname);
});
Thanks in advance!
simple bind new function with blank code
$( "#id" ).bind( "click", function() {
//blank
});
or
used
$('#id').unbind();
Try this,
var requests = [];
function replacePage(url) {
var obj = $(this);
obj.unbind("click", replacePage); //unbind to prevent ajax multiple request
var loading = '<div class="push-load"></div>';
$('.content').fadeOut(200);
$('.container').append(loading);
$.each(requests, function (i, v) {
v.abort();
});
requests.push(
$.ajax({
type: "GET",
url: url,
dataType: "html",
success: function (data) {
var dom = $(data);
//var title = dom.filter('title').text();
var html = dom.find('.content').html();
//alert(html);
//alert("OK");
//$('title').text(title);
obj.bind("click", replacePage); // binding after successfulurl ajax request
$('.push-load').remove();
$('.content').html(html).fadeIn(200);
//console.log(data);
$('.page-loader').hide();
$('.load-a').fadeIn(300);
}
}));
}
Hope this helps,Thank you

Edit image src with jQuery

I have one question I'm using this code for editing image src's thats creating js but its not working ...(after click on button jquery creating object and then this function will change src's in this created object )
that code where first creating objects and second will edit image src's
function addToplaylist(title)
{
/* some CODE */
var each = playlistts.join('</span><li><img class="plimg" src="/img/cover.png"><span onclick="playinToplaylist($(this).html());" class="titletrack">');
$("#playlist").html('<li><img onload="this.src = \'/img/playlist/\'+$(this).next(\'span.titletrack\').text()+\'.jpg\'" src="/img/cover.png"><span onclick="playinToplaylist($(this).html());" class="titletrack">' + each);
/* some CODE */
}
$(document).ready(function(){
$("body .plimg").attr("src",
function (index) {
var title = $(this).next('span.titletrack').text();
var array = title.split(' - ');
var track = array[0];
var artist = array[1];
var output;
$.ajax({ //instead of getJSON as the function does not allow configurations.
url: "http://ws.audioscrobbler.com/2.0/?method=track.search",
data: {
track: track,
artist: artist,
api_key: "ca86a16ce762065a423e20381ccfcdf0",
format: "json",
lang: "en",
limit: 1
},
async: false, //making the call synchronous
dataType: 'json', //specifying JSON type
success: function (data) {
output = data.results.trackmatches.track.image[0]["#text"];
}
});
return output;
});
});

Pausing for loop after every execution

i have a page, wherein i am using a ajax for inserting records... now in javascript i am using a for each loop to loop the html table and insert the rows in database. but happens is as foreach loop executes fast, it sometime, does not insert some records.. so i want to make the loop sleep for sometime once it has executed first and thereafter...
is there any way to pause the for loop.. i used setTImeout.. but it just delay it first time and not consecutive times...
here's my code.
function AddTopStories() {
$("#tBodySecond tr").each(function (index) {
$.ajax({
type: "POST",
url: "AjaxMethods.aspx/AddTopStoriesPosition",
data: "{'articleID':'" + $("td:nth-child(1)", this).text() + "','siteID':1}",
dataType: "json",
contentType: "application/json",
success: function (data) {
window.setTimeout(showSuccessToast(data.d), 3000);
},
error: function (data) {
window.setTimeout(showSuccessToast("Error:" + data.reponseText), 3000);
}
});
});
}
Please help me to resolve this issue... its utmost important.
*************************************UPDATED CODE AS PER THE CHANGES BY jfriend00*********
function AddTopStories() {
var stories = $("#tBodySecond tr");
var storyIndex = 0;
function addNext() {
if (storyIndex > stories.length) return; // done, no more to get
var item = stories.get(storyIndex++);
alert($("td:nth-child(1)", item).text());
addNext();
}
}
This just does not do anything... does not alert...
I'd recommend you break it into a function that does one story and then you initiate the next story from the success handler of the first like this:
function AddTopStories() {
var stories = $("#tBodySecond tr");
var storyIndex = 0;
function addNext() {
if (storyIndex >= stories.length) return; // done, no more to get
var item = stories.get(storyIndex++);
$.ajax({
type: "POST",
url: "AjaxMethods.aspx/AddTopStoriesPosition",
data: "{'articleID':'" + $("td:nth-child(1)", item).text() + "','siteID':1}",
dataType: "json",
contentType: "application/json",
success: function (data) {
addNext(); // upon success, do the next story
showSuccessToast(data.d);
},
error: function (data) {
showSuccessToast("Error:" + data.reponseText);
}
});
}
addNext();
}
Ugly, but you can fake a javascript 'sleep' using one of the methods on this website:
http://www.devcheater.com/

Categories

Resources