setTimeOut/setInterval runs just once - javascript

I use function App.loadTo to load some data in any place. I need a delay before displaying any content (used form-styler plugin, redrawing form). I tried setTimeout and setInterval functions, but they run just once, i.e.
1) Called App.loadTo( params ) - delay works
2) Called App.loadTo( params ) with the same params - delay doesnt work
I tried the following with no success
tmp = setInterval(function() {
console.log('I show all invisible!', params.where);
$(params.where).css({
'visibility': 'visible'
});
$('#preloader').remove();
clearInterval(tmp);
}, 110);
Where did I make a mistake?
App.loadTo = function loadTo(params) {
$.ajax({
url: '/' + params.controller + '/' + params.action + '',
type: 'POST',
dataType: 'json',
data: params.sentData,
success: function(server_answer, textStatus) {
if (server_answer.result == 'success') {
if (params.hasOwnProperty('parseHtml')) {
// Data parsing
var html = $(server_answer.html);
html = $(html).find(params.parseBlock);
} else {
var html = $(server_answer.html);
}
// Inserting data
$(params.where).empty().html(html).css({
'visibility': 'hidden'
}).before('<div id="preloader" style="width: 100%; background: url("i/preloader.gif") no-repeat scroll 50% center transparent; min-height: 140px; height: 100%;"></div>');
// Delay before display
setTimeout(function() {
console.log('I show all invisible!', params.where);
$(params.where).css({
'visibility': 'visible'
});
$('#preloader').remove();
}, 110);
} else {
alert_jq_ui(server_answer.error_txt);
}
},
error: function(xhr, errmsg, err) {
alert_jq_ui(xhr, errmsg, err);
}
});
};

Try clearing the setTimeout with clearTimeout(); if you choose to go with that, else if you rather want to try the setinterval method, try clearing it outside of itself, i hope this helps

I created a little fiddle, stripped down your code ... http://jsfiddle.net/gnsnvjtz/
The big difference here is this:
var App = {
loadTo: function () {
///loadTo code goes here ...
}
}
instead of `App.loadTo = function loadTo(params) ...

Related

Scroll up when you click on the pagination page

Can you please tell us how to make a scroll up when you click on the pagination page? There is a page of posts https://tvoidv.ru/culture/.
When you click on "Show more" (in itself) the page remains in place, but you need it to hide up or somehow it seems that the update has occurred. How can this be done?
Post loading code from json
$(document).on('click', '#more-news', function(e) {
e.preventDefault();
var _url = $(this).attr('data-url');
send = false; //убираем шумы
if (_url && !send) {
$.ajax({
url: _url,
type: 'GET',
dataType: 'json',
beforeSend: function() {
// включение прелоудера
send = false;
},
complete: function() {
// отключение прелоудера
},
success: function(obj) {
send = true;
$('#more-news').remove(); //удаляем текущю кнопку
$("#get_news").append(obj['html'])//добавляе готвую разметку
if('show_more' == true){
$('#more-news').show();
} else {
$('#more-news').hide();
} //добавляем кнопку если пришел флаг
},
error: function(xhr, ajaxOptions, thrownError) {
console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText + "\r\n" + xhr);
}
});
}
});
I cannot see your HTML, so assuming that #more-news is where you would want to dock to
Add this to the success block after the element is visible
var element = $('#more-news').get(0)
element.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
More options here - https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Smooth behavior is limited to certain browsers.

Is it possible to know when an ajax call has been completed in OOP approach

Sorry for the confusing title. I was at loss of words to describe it in a better manner.
So this is what is I'm trying to find out. Let's say
function myClass()
{
$.ajax({
type:'get',
url:'some/path/',
success:function(response)
{
// call has been compeleted, set some flag here
}
});
return this;
}
var obj = new myClass();
jQuery('body').append('<div id="overlay"></div>'); // so now the user will know he has to wait for some operation to be completed...
// now determine on this line whether the Ajax call is still in progress
while(<ajax call still in progress>)
{
// i do not need to do anything here since the overlay is already there in place
}
// now this is where I want to remove the overlay
jQuery('#overlay').remove();
UPDATE
Basically, I'm showing a loading overlay when the ajax call is made and once it finishes, I would like to remove that overlay. I know I can write the code inside the class itself, but I want the control of adding/removing the overlay outside the class.
You should use the promise nature of such a request. So keep a reference to what
$.ajax returns in a property of your created object.
You can then use the then method on that property to know when all is done.
Here is code making a call to a test server which shows a silver overlay while the request is pending (1 second):
function myClass(path) {
this.request = $.ajax({
// ^^^^^^^^^^^^
type: 'get',
url: path,
});
}
var obj = new myClass('https://httpstat.us/200?sleep=1000');
jQuery('body').append('<div id="overlay"></div>');
obj.request.then(function(response) {
console.log('done');
jQuery('#overlay').remove();
});
#overlay {
position: absolute;
width: 100%;
height: 100%;
background: silver;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Any attempt to make such code synchronous is bad practice. You need to embrace the asynchronous nature of Ajax calls, and use a callback system, like available through promises.
This is how I would do it:
/* The constructor. */
function myClass(successCallback) {
$.ajax({
context: this,
type: "get",
url: "some/path/",
success: function(response) {
this.inProgress = false;
successCallback.call(this);
}
});
this.inProgress = true;
}
/* Create a new class and add an overlay to the body. */
var obj = new myClass(removeOverlay);
jQuery('body').append('<div id="overlay"></div>');
/* The function that removes the overlay. */
function removeOverlay () {
if (!this.inProgress) jQuery('#overlay').remove();
}
You can pass callbacks as parameters to your object constructor:
function myClass(onStart, onStop) {
$.ajax({
type:'get',
url:'some/path',
data: {
action: 'test'
},
beforeSend: function() {
if (onStart && typeof onStart == 'function') {
onStart();
}
},
success: function(response) {
//do something
},
complete: function() {
if (onStop && typeof onStop == 'function') {
onStop();
}
}
});
}
var onStart = function () {
console.log('Started');
}
var onStop = function () {
console.log('Stopped');
}
var obj = new myClass(onStart, onStop);

clear setinterval on mouseover and resume on mouse out

I am trying to modify some existing code and can't get it working correctly. When the mouse is over div id "mine" I need the setinterval to stop and when the mouse is not over the div for the set interval to resume. I've tried and tried all day and night to get this working and just don't seem to be able to do it. Any help would be greatly appreciated. Thank you.
jQuery(document).ready(function(){
// check all
jQuery(this).on('click', '#selectall', function() {
jQuery('.checkbox').prop('checked', jQuery(this).is(":checked"));
});
// ajax
jQuery(this).on('submit', 'form[name="dispatchform"]', function(){
jQuery.ajax({
url: jQuery(this).attr('action'),
data: jQuery(this).serialize(),
type: 'post',
beforeSend: function(){jQuery('body').css('opacity', '0.5');},
success: function(data) {
var response = jQuery(data).find('#dispatchTable').html();
jQuery('#dispatchTable').html(response);
//message
var msg = jQuery(data).find('td.messageStackError, td.messageStackSuccess').html();
jQuery('#msg').css({
'padding': '10px',
'text-align': 'center',
'font-size': '12px',
'background-color': 'darkkhaki',
'margin': '10px 0',
'color': '#fff'
}).html(msg);
},
complete: function(){jQuery('body').css('opacity', '1');}
});
return false;
});
setInterval(function() {
jQuery.ajax({
url: jQuery(this).attr('action'),
data: jQuery(this).serialize(),
type: 'post',
beforeSend: function(){jQuery('body').css('opacity', '0.5');},
success: function(data) {
var response = jQuery(data).find('#dispatchTable').html();
jQuery('#dispatchTable').html(response);
//message
var msg = jQuery(data).find('td.messageStackError, td.messageStackSuccess').html();
if(msg !== undefined) {
jQuery('#msg').css({
'padding': '10px',
'text-align': 'center',
'font-size': '12px',
'background-color': 'darkkhaki',
'margin': '10px 0',
'color': '#fff'
}).html(msg);
}
},
complete: function(){jQuery('body').css('opacity', '1');}
});
}, 15000);
});
I'm not sure where, exactly you want that to happen...
What I mean is that I don't see div#mine anywhere in that code, so I don't know if it's supposed to be inside of one of those, or outside of all of them, or both outside, and also inside, if under special circumstances...
...regardless, the general idea is the following:
var doSomethingId;
function doSomething ( ) { }
var mine = document.querySelector("#mine");
mine.addEventListener("mouseover", function () {
doSomething();
doSomethingId = setInterval(doSomething, 10000);
});
mine.addEventListener("mouseout", function () {
clearInterval(doSomethingId);
});
There's not a whole lot more to it than that. The jQuery also isn't much smaller.
The key is to save the ID (var id = setInterval(/*...*/);) and use it to clear the interval (clearInterval(id);).
You don't "restart" the interval; rather, you call id = setInterval(...); again, so that the id is now the new interval, so you can stop the new interval.
Edit:
This is really an "XY" problem...
That is to say that you're looking for a solution to a problem that isn't really at the root of your problems, but rather a problem that is an offshoot, on top of the root.
A quick example:
most forms, I fill out by tabbing into, tabbing through the fields, and then either hitting ENTER, or tabbing down to the submit button and hitting ENTER
In this case (people who use keyboards/touchscreens/etc), you're still going to have the problem you're facing, now.
That said, if you're willing to refactor a little, the solution can be the same.
What I mean is, instead of your `setInterval(function () { jQuery./.../ });
What you want to do is something like;
var shouldUpdate = true,
form = this,
$mine = jQuery("#mine");
$mine.on("mouseover", function () { shouldUpdate = false; });
$mine.on("mouseout", function () { shouldUpdate = true; });
// whole setInterval(function () { jQuery.ajax(...); }); copied and pasted here, plus the `if`
function submitForm () {
if (!shouldUpdate) { return; }
jQuery.ajax(/* ... */);
}
var submitId = setInterval(submitForm, 15000);
// clearInterval(submitId); -- just remember to set the new ID, if you restart it
As you can see, I don't really need the interval to be started and stopped, now.
I've got an if that returns if I'm in any state that I shouldn't be updating in
(really, this should go one step further, and abort any XHR calls that are already happening, if you do start editing a field).
Based on this post I guess you'd like to accomplish something like this?
<!DOCTYPE html>
<html>
<head>
<style>
#mine{
width:200px;
height:200px;
border:1px solid red;
}
</style>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<p>Counter:</p>
<div id="mine"></div>
<div id="counter">
</div>
<script>
jQuery(document).ready(function(){
$( "#mine" )
.mouseout(function() {
enableCounter();
})
.mouseover(function() {
disableCounter();
});
});
var count=10;
var counterEnabled = true;
var counter=setInterval(timer, 1000); //run every 1 second
function timer(){
if (counterEnabled)
count--;
if (count == 0){
alert('execute submit here!');
count = 10;
}
$('#counter').text(count);
}
function enableCounter(){
counterEnabled = true;
}
function disableCounter(){
counterEnabled = false;
}
</script>
</body>
</html>

Append more content when scroll to end of page

Hi I only started working on JQuery Mobile a month ago and my starting project was to build an app to load my blog posts. After spending days and night researching and support from SO, I did manage to get my blog posts loaded and also added a Load More link to append new contents.
My intention no is rather than use a link, I want the new contents appended when I scroll to end of page. I do not plan to use a plugin for now but was hoping I could write a simple code to do that for me. This is my current code (First function to load initial contenst while the 2nd function is to append more contents. Not sure if this is the best approach but like I said, I am still in learning process)
$(document).on('pagebeforeshow', '#blogposts', function () {
$.ajax({
url: "http://howtodeployit.com/?json=recentstories",
dataType: "json",
beforeSend: function () {
$('#loader').show();
},
complete: function () {
$('#loader').hide();
},
success: function (data) {
$('#postlist').empty();
$.each(data.posts, function (key, val) {
//Output data collected into page content
var rtitle = $('<p/>', {
'class': 'vtitle',
html: val.title
}),
var rappend = $('<li/>').append(rtitle);
$('#postlist').append(rappend);
return (key !== 5);
});
$("#postlist").listview().listview('refresh');
},
error: function (data) {
alert("Service currently not available, please try again later...");
}
});
});
$(document).on("click", ".load-more", function () {
$.getJSON("http://howtodeployit.com/?json=recentstories", function (data) {
var currentPost = $('#postlist');
console.log(currentPost);
loadMore = currentPost.parent().find('.load-more');
var currentPostcount = $('#postlist li').length;
console.log(currentPostcount);
var desiredPosts = 3;
newposts = data.posts.slice(currentPostcount, currentPostcount + desiredPosts);
$.each(newposts, function (key, val) {
var rtitle = $('<p/>', {
'class': 'vtitle',
html: val.title
}),
var rappend = $('<li/>').append(rtitle);
$('#postlist').append(rappend);
$("#postlist").listview('refresh');
});
});
});
Sorry if this type of question had been answered else where. Please post link
This is a typical approach with jquery,
$(window).scroll(function () {
if ($(window).scrollTop() == $(document).height() - $(window).height()) {
/*end reached*/
$('.content').html($('.content').html()+"more</br></br></br></br>");
}
});
example with jqm,
http://jsfiddle.net/F5McF/
Try this example it works.
function loaddata()
{
var el = $("outer");
if( (el.scrollTop + el.clientHeight) >= el.scrollHeight )
{
el.setStyles( { "background-color": "green"} );
}
else
{
el.setStyles( { "background-color": "red"} );
}
}
window.addEvent( "domready", function()
{
$("outer").addEvent( "scroll", loaddata );
} );
Fiddle is
http://jsfiddle.net/wWmqr/1/

Activate jquery Ajax on click on list and pull number

This is my code that I have built from several different pieces of information online:
http://jsfiddle.net/spadez/qKyNL/6/
$.ajax({
url: "/ajax_json_echo/",
type: "GET",
dataType: "json",
timeout: 5000,
beforeSend: function () {
// Fadeout the existing content
$('#content').fadeTo(500, 0.5);
},
success: function (data, textStatus) {
// TO DO: Load in new content
// Scroll to top
$('html, body').animate({
scrollTop: '0px'
}, 300);
// TO DO: Change URL
// TO DO: Set number as active class
},
error: function (x, t, m) {
if (t === "timeout") {
alert("Request timeout");
} else {
alert('Request error');
}
},
complete: function () {
// Fade in content
$('#content').fadeTo(500, 1);
},
});
My question is, how do I trigger the ajax request from clicking on one of the pagination list links (like 1 or 2) whilst using e.prevent default so it is degradable (it will still work if JavaScript is disabled). I guess what I am trying to do is the following in pseudo code:
Listen for a click of the pagination link
Grab the number of the link clicked (ie was 1 or 2 clicked)
try
$('a').click(function(){
var number = $(this).attr('href');//get the pg=1 value on the href
alert(number);
//ajax here
});
I'm not sure I completely understand your question, however something like this should work:
$(function() {
var clicks = {};
var sendAjax = function(href) {
//do something with href
$.ajax({
url: "/ajax_json_echo/",
type: "GET",
dataType: "json",
timeout: 5000,
beforeSend: function () {
// Fadeout the existing content
$('#content').fadeTo(500, 0.5);
},
success: function (data, textStatus) {
// TO DO: Load in new content
// Scroll to top
$('html, body').animate({
scrollTop: '0px'
}, 300);
// TO DO: Change URL
// TO DO: Set number as active class
},
error: function (x, t, m) {
if (t === "timeout") {
alert("Request timeout");
} else {
alert('Request error');
}
},
complete: function () {
// Fade in content
$('#content').fadeTo(500, 1);
},
});
};
$('a').click(function() {
var href = $(this).attr('href');
clicks[href] = clicks[href] ? clicks[href] + 1 : 1;
sendAjax(href);
return false; //disable the link
});
});
can't you just set an onclick on those link 1 and link 2?
ex:
link1.click(function() {
// do stuff with the ajax
});

Categories

Resources