I have a problem with ajax call after success.
I am trying to call my following javascript codes:
function imgResize($, sr) {
var debounce = function(func, threshold, execAsap) {
var timeout;
return function debounced() {
var obj = this,
args = arguments;
function delayed() {
if (!execAsap)
func.apply(obj, args);
timeout = null;
};
if (timeout)
clearTimeout(timeout);
else if (execAsap)
func.apply(obj, args);
timeout = setTimeout(delayed, threshold || 100);
};
}
// smartresize
jQuery.fn[sr] = function(fn) {
return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr);
};
};
//CALL ON PAGE LOAD OR ANY TIME YOU WANT TO USE IT
imgResize(jQuery, 'smartresize');
/* Wait for DOM to be ready */
// Detect resize event
$(window).smartresize(function() {
// Set photo image size
$('.photo-row').each(function() {
var $pi = $(this).find('.photo-item'),
cWidth = $(this).parent('.photo').width();
// Generate array containing all image aspect ratios
var ratios = $pi.map(function() {
return $(this).find('img').data('org-width') / $(this).find('img').data('org-height');
}).get();
// Get sum of widths
var sumRatios = 0,
sumMargins = 0,
minRatio = Math.min.apply(Math, ratios);
for (var i = 0; i < $pi.length; i++) {
sumRatios += ratios[i] / minRatio;
};
$pi.each(function() {
sumMargins += parseInt($(this).css('margin-left')) + parseInt($(this).css('margin-right'));
});
// Calculate dimensions
$pi.each(function(i) {
var minWidth = (cWidth - sumMargins) / sumRatios;
$(this).find('img')
.height(Math.floor(minWidth / minRatio))
.width(Math.floor(minWidth / minRatio) * ratios[i]);
});
});
});
/* Wait for images to be loaded */
$(window).load(function() {
$(".photo").each(function() {
var imgGrab = $(this).find('.photo-item');
var imgLength = imgGrab.length;
for (i = 0; i < imgLength; i = i + 3) {
imgGrab.eq(i + 1)
.add(imgGrab.eq(i + 1))
.add(imgGrab.eq(i + 2))
.wrapAll('<div class="photo-row"></div>');
}
$(this).find(".photo-item").each(function() {
if ($(this).parent().is(":not(.photo-row)")) {
$(this).wrap('<div class="photo-row"></div>');
}
});
// Store original image dimensions
$(this).find('.photo-item img').each(function() {
$(this)
.data('org-width', $(this)[0].naturalWidth)
.data('org-height', $(this)[0].naturalHeight);
});
});
$(window).resize();
});
And here is my ajax code for LOAD MORE POST
$('body').on("click",'.morep', function(event) {
event.preventDefault();
var ID = $(this).attr("id");
var P_ID = $(this).attr("rel");
var URL = $.base_url + 'more_post.php';
var dataString = "lastpid=" + ID + "&post_id=" + P_ID;
if (ID) {
$.ajax({
type: "POST",
url: URL,
data: dataString,
cache: false,
beforeSend: function() {
$("#more" + ID).html('<img src="loaders/ajaxloader.gif" />');
},
success: function(html) {
$("div.post-content").append(html);
$("#more" + ID).remove();
imgResize(jQuery, 'smartresize');
}
});
} else {
$("#more").html('FINISHED');
}
return false;
});
The ajax should call imgResize(jQuery, 'smartresize'); but it is not working. What I am missing here anyone can help me here ?
Related
So I get multiple objects from a REST API.
I get the data via AJAX like this:
var APICaller = (function () {
let endpoint = "https://jsonplaceholder.typicode.com/";
function api_call(method, url, data, callback) {
$.ajax({
url: url,
method: method,
data: data,
success: callback
});
}
function get_users(callback) {
let method = "GET";
let url = endpoint + "users";
let data = {};
api_call(method, url, data, callback);
}
return {
get_users: get_users,
};
})();
I am rolling 3 dices, and the total values of these 3 dices should be attached to each user so i can order the "scoreboard" after the total value.
I wonder if there is any way to attach the variable totalamount to every user?
Thanks in advace!
EDIT:
Currently i am getting all the users from the api.
This is the rest of my code withing this topic:
var Game = (function () {
var dice_total;
//Function for when the dice rolls.
function roll_dice() {
var value1 = $(".val1");
var value2 = $(".val2");
var value3 = $(".val3");
var v1 = Math.floor(Math.random() * 6) + 1;
var v2 = Math.floor(Math.random() * 6) + 1;
var v3 = Math.floor(Math.random() * 6) + 1;
value1.html(v1);
value2.html(v2);
value3.html(v3);
dice_total = v1 + v2 + v3;
}
return {
roll_dice: roll_dice
};
})();
var EventHandlers = (function () {
function init() {
var currentPlayer;
APICaller.get_users(on_get_users_success);
function on_get_users_success(response) {
//For each user in the API
$.each(response, function (i, user) {
$("#my-list").append('<li class="list-li"><a class="list-a">' + user.name + '</a></li>');
//Create the divs and p tags
$("#dice_value").append('<div class="val_div"> <p class="val1"></p> <p class="val2"></p> <p class="val3"></p></div>');
});
//change information
$("#info-txt").text("Välj en spelare!");
}
// On klick on a user make klicked user your own player.
$("#my-list").on('click', '.list-a', function () {
currentPlayer = this.text;
$("#info-txt").text("Tryck på spela knappen för att börja spelet!");
$("#currentPlayer-div").animate({
height: '300px',
opacity: '1'
});
$("#currentPlayer-h3").text(currentPlayer);
});
// On klick of the play button
$("#startGame-button").click(function () {
$().animate();
$("#currentPlayer-div").animate({
height: '150px'
});
$("#startGame-button").animate({
opacity: '0'
});
$("#dice_value").animate({
opacity: '1'
});
Game.roll_dice();
});
// $(".button-to-hide").click(function (){
// $(this).hide();
// });
// $("#show-all-buttons").click(function (){
// $(".button-to-hide").show();
// });
// $("#btn-edit-text").click(function (){
// var value = $("#my-input").val();
// $("p").html(value);
// });
}
return {
init: init,
}
})();
var DocumentEdit = (function () {
return {
}
})();
$(document).ready(function () {
EventHandlers.init();
});
Hope that describes it.
So I have a loop, which performs an ajax call on each iteration and I want to set the progress bar updated.. But it is not updating, it goes to 100% directly when ending...
I've tried to put the bar update call outside the success action (inside the loop directly) but it isn't working either..
$('button.page').on('click', function(e){
var $userList = textArray($('#page-userlist').val().replace('http://lop/', '').split(/\n/));
var $proxyList = textArray($('#page-proxylist').val().replace('http://', '').split(/\n/));
var $question = $('#page-question').val();
var data = {
question: $question,
users: $userList,
proxies: $proxyList
};
var i = 0, p = 0, max = data.proxies.length, totalusers = data.users.length, percent = 0;
$('#log').append("\n" + moment().calendar() + "\n");
var progressbar = $('#page-progress');
$.each(data.users, function(k, u){
if(typeof(p) !== 'undefined' && p !== null && p > 0)
{
if(i % 10 == 0 && i > 1) p++;
if(p == max) return false;
}
var proxy = data.proxies[p];
percent = Math.round((i / totalusers) * 100);
$.ajax({
type: "POST",
url: Routing.generate('viral_admin_bot_page'),
data: {question: $question, user: u, proxy: proxy},
success: function(result) {
$('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
$(progressbar).width(percent + "%");
},
error: function(error) {
$('#log').append(error);
}
});
i++;
});
});
If i do console.log(percent); it is updating perfectly on each iteration, so I don't know where can be the problem.
Here is my code (without the ajax call because it isn't the problem) http://jsfiddle.net/dvo1dm03/20/
it will output to console the percentage, the objetive is to update the bar to the percentage completed in each loop, so it goes in "realtime" with loop.
Ok, here's how to do it asynchrounously.
var speed = 75;
var number_of_calls_returned = 0; // add number_of_calls_returned++ in your ajax success function
var number_of_total_calls;
var loaded = false;
function processUserData(){
if( number_of_calls_returned < number_of_total_calls){
setTimeout(function(){processUserData();}, 200);
}
else{
//received all data
// set progressbar to 100% width
loaded = true;
$("#page-progress").animate({width: "100%"},500);
$("#page-proxylist").val("Received data");
}
}
function updateProgress(percent, obj){
setTimeout(function(x){
if(!loaded)
$(obj).width(x + "%");
}, percent*speed, percent);
}
$('button.page').on('click', function (e) {
var $userList = textArray($('#page-userlist').val().replace('http://lop/', '').split(/\n/));
var $proxyList = textArray($('#page-proxylist').val().replace('http://', '').split(/\n/));
var $question = $('#page-question').val();
var data = {
question: $question,
users: $userList,
proxies: $proxyList
};
var i = 0,
p = 0,
max = data.proxies.length,
totalusers = data.users.length,
percent = 0;
//$('#log').append("\n" + moment().calendar() + "\n");
var progressbar = $('#page-progress');
number_of_total_calls = totalusers;
$.each(data.users, function (k, u) {
if (typeof (p) !== 'undefined' && p !== null && p > 0) {
if (i % 10 == 0 && i > 1) p++;
if (p == max) return false;
}
var proxy = data.proxies[p];
percent = (i / totalusers) * 100; //much smoother if not int
updateProgress(percent, progressbar);
i++;
// simulate ajax call
setTimeout(function(){number_of_calls_returned++;}, Math.random()*2000);
});
//callback function
setTimeout(function(){processUserData();}, 200);
});
var textArray = function (lines) {
var texts = []
for (var i = 0; i < lines.length; i++) {
// only push this line if it contains a non whitespace character.
if (/\S/.test(lines[i])) {
texts.push($.trim(lines[i]));
}
}
return texts;
}
Check it out here! jsFiddle (really cool!)
Your problem is cause by the fact that you have a closure for your success function and every success function shares the same percent variable. You can fix it like this:
success: function(percent, result) {
$('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
$(progressbar).width(percent + "%");
}.bind(percent),
Where you'll need to shim bind in older browsers, or like this, which is a little uglier, but should work everywhere without a shim:
success: (function(percent) { return function(result) {
$('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
$(progressbar).width(percent + "%");
}; }( percent ),
if what you want is to increase the update bar with each success of AJAX calls I'd suggest an easier solution (I've simplified the js code for clarity's sake):
$('button').click(function (e) {
var i = 0,
cont = 0,
totalusers = 100,
percent = 0;
var progressbar = $('#page-progress');
for (; i < totalusers; i++) {
$.ajax({
type: "POST",
url: '/echo/json/',
data: {
question: 'something',
user: 1,
proxy: 2
},
success: function (result) {
cont += 1;
percent = Math.round((cont / totalusers) * 100);
progressbar.width(percent + "%");
},
error: function (error) {
$('#log').append(error);
}
});
};
});
You can see it in action in this fiddle.
Hope this helps or at least give you some ideas.
Update the progress bar using setTimeout method.
it will wait for some time and then update the width of progressbar.
myVar = setTimeout("javascript function",milliseconds);
Thanks,
Ganesh Shirsat
I would like to make a recommendation of trying to make a self contained example that doesn't rely on the post so that it is easier for you or us to solve the problem
As well, you can console log elements so you could try logging the progressbar element, percent and the response of the ajax request
(This code is to replace the javascript sections of the fiddler)
var i = 0;
moveProgress();
function moveProgress(){
if(i < 10000)
{
setTimeout(function(){
$('#page-progress').width((i / 1000) * 100);
moveProgress();
},2);
i++;
}
}
The reason that it wasn't working was because the loop ran so fast that it was loaded by the time the script loaded it, the timeout allows you to delay the execution a bit(Though not necessarily recommended to use because of potential threading issues.
See below. I'm trying to pass function(response) as a variable to be used in a progress bar function. That's the idea anyways. How do I call back the data = response to the var i = data in this case?
$(document).ready(function () {
$.ajaxSetup({
cache: false
});
var data = 0;
setInterval(function () {
$('#divToRefresh').load('usercounter.php', function (response) {
data = response;
});
}, 100);
window.onload = function () {
var Animator = new function () {
var parent = document.getElementById('container');
var element = document.getElementById('test');
var target = document.getElementById('message');
this.move = function () {
var i = data;
var width = 0;
var timer = window.setTimeout(function () {
i += 1;
element.style.width = width + i + 'px';
}, 10);
};
};
Animator.move();
};
});
Not sure how your animator works or how those elements interact, but I'm guessing your goal is to call move periodically to refresh it's current status? So put that in the interval, and then make the retrieval of the count part of the animation. Not sure if that'll work for your scenario.
$(document).ready(function () {
$.ajaxSetup({
cache: false
});
window.onload = function () {
var Animator = new function () {
var parent = document.getElementById('container');
var element = document.getElementById('test');
var target = document.getElementById('message');
this.move = function () {
$('#divToRefresh').load('usercounter.php', function (response) {
var i = response;
var width = 0;
var timer = window.setTimeout(function () {
i += 1;
element.style.width = width + i + 'px';
}, 10);
});
};
};
Animator.move();
setInterval(function () {
Animator.move();
}, 100);
};
});
main.html
<script src="jsv3/onload.js"></script>
<script>
var countImage = 0;
function load_pages(page) {
$.ajax({
type: "GET",
url: "scandir.php",
data: "page=" + page,
dataType: 'json',
success: function (data) {
var num = 0;
var cache = [];
var startNum = 0;
var endNum = 0;
$.each(data, function(i,paths){
if ( !(page == countImage) && !(page+1 == countImage))
{
if (paths[0] != ''){
num = parseInt(paths[0].split("_P")[1],10);
if (!$('#img_'+num).length){
$("#div_"+num).append("<img id = 'img_"+num+"' src = '"+paths[0]+"' alt = 'flip book' />");
}
cache.push (num);
}
if (paths[1] != ''){
num = parseInt(paths[1].split("_P")[1],10);
if (!$('#img_'+num).length){
$("#div_"+num).append("<img id = 'img_"+num+"' src = '"+paths[1]+"' alt = 'flip book' />");
}
cache.push (num);
}
}
});
startNum = cache[0];
endNum = cache[cache.length-1];
for (var z = 0; z < 2; z++) {
startNum--;
if ($('#img_'+startNum).length){
$("#img_"+startNum+":last-child").remove();
}
}
for (var x = 0; x < 2; x++) {
endNum++;
if ($('#img_'+endNum).length){
$("#img_"+endNum+":last-child").remove();
}
}
/*if ($('#img_6').length)
alert ('img6 exist');
else
alert ('img6 not exist');*/
}
});
}
function create_div() {
var counter = 1;
$.ajax({
type: "GET",
url: "countImg.php",
dataType: 'json',
success: function (data) {
//$("#book").append("<div id='cover'></div>");
countImage = data;
for (var j = 0; j < data; j++) {
$("#book").append("<div id = 'div_"+counter+"'></div>");
counter++;
}
counter = 1;
}
});
}
$(document).ready(function(){
console.log('test');
create_div();
});
</script>
onload.js( call the init function):
/* = Start
-------------------------------------------------------------- */
$(window).bind('keydown', function(e){
if (e.keyCode==37)
$('#book').turn('previous');
else if (e.keyCode==39)
$('#book').turn('next');
});
/* Moved to the html file (FlipV5.html) to ensure the page loading is finished before initialize turn.js */
$(window).load(function(){
$('#page').show();
Book.init();
if (isiPhone()) {
$('#page').addClass('mobile');
} else {
Book.zoom_auto();
Book.book_position();
}
Book.dragdrop_init();
Navigation.init();
calculate_zoom_factor();
});
$(window).resize(function() {
if (!isiPhone()) {
Book.book_position();
Book.zoom_auto();
Book.dragdrop_init();
}
calculate_zoom_factor();
});
function resizeDetect() {
var rtime = new Date(1, 1, 1, 1,00,00);
var timeout = false;
var delta = 200;
$(window).resize(function() {
rtime = new Date();
if (timeout === false) {
timeout = true;
setTimeout(resizeend, delta);
}
});
function resizeend() {
if (new Date() - rtime < delta) {
setTimeout(resizeend, delta);
} else {
timeout = false;
window_width = $(window).width();
window_height = $(window).height();
if ( $(window).width() > $(window).height() ) {
//Book.scaleVertical();
} else {
}
}
}
}
resizeDetect();
onload.js (init function)
init: function() {
default_book_width = WIDTH_BOOK;
default_book_height = HEIGHT_BOOK;
default_page_width = WIDTH_BOOK;
default_page_height = HEIGHT_BOOK;
window_height = $(window).height();
window_width = $(window).width();
zoom_steps = ZOOM_STEPS_LENGTH;
current_zoom_step = 0;
dbl_clicked = false;
on_start = true;
self = this;
$('#book').turn({
display: 'double',
acceleration: true,
elevation:50,
when: {
first: function(e, page) {
$('.nav_arrow.prev').hide();
},
turned: function(e, page) {
if (page > 1) {
$('.nav_arrow.prev').fadeIn();
$('#about').hide();
}
if ( page < $(this).turn('pages') ) {
$('.nav_arrow.next').fadeIn();
}
pageNo = $('#book').turn('page');
load_pages(pageNo);
},
turning: function(e, page) {
if (page < 2) {
$('#about').show();
}
},
last: function(e, page) {
$('.nav_arrow.next').hide();
}
}
});
Book.arrows();
},
scaleHorizontal: function() {
new_width = $(window).width()-100;
ratio = new_width / $('#page').width();
new_height = $('#page').height() * ratio;
$('#page').css({
width: new_width,
height: new_height
});
$('#book').turn('size', new_width, new_height);
},
scaleStart: function() {
if ( on_start == true ) {
bookHeightCheck();
if ( higherThanWindow == true ) {
Book.scaleVertical();
if ( $('#page').width() > $(window).width() ) {
Book.scaleHorizontal();
}
} else {
Book.scaleHorizontal();
}
on_start = false;
}
},
The flow is like that: main.html call create_div to do some function, and since it append the onload.js, it runs Book.init() , which will call the load_pages function. So, I believe the problem is due to two ajax call is implement at the same time?
The create_div() ajax accidentally detected the ajax call in load_pages is success, so it runs two time the success function.
How to fix the problem like this? Thanks
here i am trying to achieve infinite scrolling but what happens when i am scrolling too fast it fire multiple ajax request with same parameter , which cause same data again n again.how overcome from this problem pls help.
(function( $ ){
$.fn.scrollPagination = function(options) {
var opts = $.extend($.fn.scrollPagination.defaults, options);
var target = opts.scrollTarget;
if (target == null){
target = obj;
}
opts.scrollTarget = target;
return this.each(function() {
$.fn.scrollPagination.init($(this), opts);
});
};
$.fn.stopScrollPagination = function(){
return this.each(function() {
$(this).attr('scrollPagination', 'disabled');
});
};
var itr = 2;
$.fn.scrollPagination.loadContent = function(obj, opts){
var target = opts.scrollTarget;
var mayLoadContent = $(target).scrollTop()+opts.heightOffset >= $(document).height() - $(target).height();
if (mayLoadContent){
if (opts.beforeLoad != null){
opts.beforeLoad();
}
$(obj).children().attr('rel', 'loaded');
$.ajax({
type: 'POST',
url: opts.contentPage+"?iteration="+itr,
data: opts.contentData,
success: function(data){
itr++;
$(obj).append(data);
var objectsRendered = $(obj).children('[rel!=loaded]');
if (opts.afterLoad != null){
opts.afterLoad(objectsRendered);
}
}
});
}
};
$.fn.scrollPagination.init = function(obj, opts){
var target = opts.scrollTarget;
$(obj).attr('scrollPagination', 'enabled');
$(target).scroll(function(event){
if ($(obj).attr('scrollPagination') == 'enabled'){
$.fn.scrollPagination.loadContent(obj, opts);
//alert(event.isPropagationStopped());
}
//event.stopPropagation();
//console.log(event.isPropagationStopped());
event.preventDefault();
});
//$.fn.scrollPagination.loadContent(obj, opts);
};
$.fn.scrollPagination.defaults = {
'contentPage' : null,
'contentData' : {},
'beforeLoad': null,
'afterLoad': null ,
'scrollTarget': null,
'heightOffset': 0
};
})( jQuery );
How about firing off the ajax every 10 times the scroll event is triggered?
$.fn.scrollPagination.init = function(obj, opts) {
var target = opts.scrollTarget;
$(obj).attr('scrollPagination', 'enabled');
target.scrollCount = 0;
$(target).scroll(function(event) {
this.scrollCount++;
if (this.scrollCount % 10 == 0) {
if ($(obj).attr('scrollPagination') == 'enabled') {
$.fn.scrollPagination.loadContent(obj, opts);
//alert(event.isPropagationStopped());
}
//event.stopPropagation();
//console.log(event.isPropagationStopped());
event.preventDefault();
}
});
}
I used to call my ajax function when the scroll reaches the bottom of the page.
function nearBottomOfPage() {
return $(window).scrollTop() > $(document).height() - $(window).height() - 200;
}
$(window).scroll(function(){
if (loading) {
return;
}
if(nearBottomOfPage()) {
loading=true;
page++;
$("#place_of_loading_image").show();
$.ajax({
url:'your source',
type: 'get',
dataType: 'script',
success: function() {
$("#place_of_loading_image").remove();
loading=false;
}
});
}
});