I would like to update some <div> in a given time interval.
Let say every 3 seconds call mypost() function.
How to do that in jquery?
Thanks
Arman.
There's nothing in jquery that allows you to do this because there's the native javascript window.setInterval function:
window.setInterval(function() {
// this will be invoked on every 5s
$.post(...);
}, 5000);
If you want to invoke it only once:
window.setTimeout(function() {
// this will be invoked after 5s only once
$.post(...);
}, 5000);
Related
I am using the following libraries in the relevant application: Angular 4.x, ngrx 4.x, rxjs 5.4.x
I have an api that I need to poll every 5 minutes. The user is also able to manually refresh the data. That data is stored in an ngrx store. I am using ngrx effects so the data is retrieved by dispatching an action of type 'FETCH'.
I want to setup a rxjs stream where it will dispatch the 'FETCH' action to the ngrx store. It will be a sliding 5 minute timer that resets when the user manually updates the store. The stream should initially emit a value when subscribed.
I'm not sure how I can reset the timer. In plain javascript I would do something like the following:
console.clear();
let timer;
let counter = 0;
function fetch() {
console.log('fetch', counter++);
poll();
}
function poll() {
if (timer != null) {
window.clearTimeout(timer);
}
timer = window.setTimeout(() => {
console.log('poll');
fetch();
}, 5000);
}
function manualGet() {
console.log('manual');
fetch();
}
fetch();
<button onClick="manualGet()">Get Data</button>
Question: How do I emit on an interval that is reset when another stream emits like the example again?
You want two components to your stream – a timer and some user input. So let's start with the user input. I'll assume some button which can be clicked:
const userInput$ = Observable.fromEvent(button, 'click');
Now we want to start a timer which resets everytime userInput$ emits. We can do that using
userInput$.switchMap(() => Observable.timer(0, 5000));
However, we also want this stream to start without the user having to first click the button. But that's also not a problem:
userInput$.startWith(null);
Now we put it all together:
Observable.fromEvent(button, 'click')
.startWith(null)
.switchMap(() => Observable.timer(0, 5000))
.subscribe(() => dispatchFetch());
Note that I am following your examples of using a 5 second timer, not a 5 minute timer (which you mentioned in the question.)
After writing it out in vanilla JS I realized that the source of the timer should be the data. I was struggling to figure out what the source would be. Clearly it couldn't be the timer since I needed to reset it.
I'm open to better options but here is how I solved it:
console.clear();
let counter = 0;
const data = new Rx.BehaviorSubject(null);
function fetch() {
data.next(counter++);
}
function manualGet() {
console.log('manual');
fetch();
}
// setup poll
data.switchMap(() => Rx.Observable.timer(5000))
.subscribe(() => {
console.log('poll');
fetch();
});
// subscribe to the data
data.filter(x => x != null).
subscribe(x => { console.log('data', x); });
// do the first fetch
fetch();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.5/Rx.min.js"></script>
<button onClick="manualGet()">Get Data</button>
With ngrx I am listening for the success action related to the fetch event.
Lets say we have a form with a jquery validation. Now we create a simple Jasmine spec and want to test if the error message is visible if we submit an empty form.
My first step is to trigger the submit form event after that jquery validate will work and show the error messages. The time window until the error message will be displayed is really small (2ms) but too big for a Jasmine test. Currently with a setTimeout() it works but I think that is a bad way :(
I am new to Jasmine and I think there must be a better way? Something with spy?
Dummy spec for example:
describe("Lorem Impsum: ", function () {
it("Form validation shows error messages.", function () {
$("#MyForm").submit();
expect($(".error")).toBeVisible();
});
});
Using setTimeout or setInterval for polling may not be a bad way. If the page is complicated, periodic checks are simpler, than using MutationObserver. (This is a unit test; not an application.) If you choose the polling interval short enough, the test will not be so slow. For example:
describe("Lorem Impsum: ", function () {
it("Form validation shows error messages.", function (done) {
$("#MyForm").submit();
waitForElement(".error", function () {
expect($(".error")).toBeVisible();
done();
});
});
});
function waitForElement(selector, callback) {
var interval;
if ($(selector).length) {
callback();
} else {
interval = setInterval(function () {
if ($(selector).length) {
clearInterval(interval);
callback();
}
}, 10);
}
}
You will need to declare and call the done callback, so that Jasmine gets notified, when the test spec has finished.
I have the following script, it reloads the forum topics every 3 seconds but I also want it to load as soon as the page loads, so that there is no delay the first time. The first time the page loads it takes 3 seconds before the topics show up.
Can anyone help me with this?
Thanks in advance.
<script type="text/javascript">
window.onload = function(){
function foo()
{
$('#forum').load('forum.php').fadeIn("slow");
} // refresh every 10000 milliseconds
setInterval(foo, 3000);
}
</script>
That is because you are waiting on the .onload event, which is fired when all resources/assets (like images) have been downloaded by the browser — this delay will be significant on bloated or resource-heavy sites, which will make a lot of HTTP requests and does not fire the onload event as early as you wish.
The solution? You should instead fire foo on DOM ready:
$(function() {
var foo = function() {
$('#forum').load('forum.php').fadeIn("slow");
}
// Will execute on DOM ready
foo();
setInterval(foo, 3000);
});
Note that $(function() {...}) is the equivalent of $(document).ready(function() {...}) in jQuery.
If you wish to also forcibly fire foo() when all resources are loaded up, just fire it again with:
$(function() {
var foo = function() {
$('#forum').load('forum.php').fadeIn("slow");
}
// Will execute on DOM ready
foo();
setInterval(foo, 3000);
// Also execute on window load
$(window).load(foo);
});
I am using addNotice to display any message on screen. Now, I want to customize it and it should be removed after some time(let's say after 10 seconds) like we can do with javascript.
Is this possible to do this using default addNotice message of magento ?
Any Help would be appreciated.
add this script in your page
This will hide the div after 1 second (1000 milliseconds).
$(function() {
setTimeout(function() {
$('.messages').fadeOut('fast');
}, 1000); // <-- time in milliseconds
});
If you just want to hide without fading, use hide().
hope this will help you
Add this to your footer:
setTimeout(function(){
var messages = $$('.messages')[0];
if (messages){
$(messages).hide();
}
}, 10000)
The code above is the prototype version.
If you have jquery already in your website use what #magExp wrote. It's cleaner.
Let say your success message id is "success-msg", then write jquery like
$(function() {
// setTimeout() function will be fired after page is loaded
// it will wait for 5 sec. and then will fire
// $("#success-msg").hide() function
setTimeout(function() {
$("#success-msg").hide('blind', {}, 1000)
}, 5000);
});
Remember that you need to load jQuery Library..
I'm triyng to build a simple animation jQuery-plugin. The main idea is to take an element and manipulate it in some way repeatedly in a fixed intervall which would be the fps of the animation.
I wanted to accomplish this through events. Instead of using loops like for() or while() I want to repeat certain actions through triggering events. The idea behind this: I eventualy want to be able to call multiple actions on certain events, like starting a second animation when the first is done, or even starting it when one animation-sequence is on a certain frame.
Now I tried the following (very simplified version of the plugin):
(function($) {
$.fn.animation = function() {
obj = this;
pause = 1000 / 12; //-> 12fps
function setup(o) {
o.doSomething().trigger('allSetUp');
}
function doStep(o, dt) {
o.doSomething().delay(dt).trigger('stepDone');
}
function sequenceFinished(o) {
o.trigger('startOver');
}
function checkProgress(o) {
o.on({
'allSetup': function(event) {
console.log(event); //check event
doStep(o, pause);
},
'stepDone': function(event) {
console.log(event); //check event
doStep(o, pause);
},
'startOver': function(event) {
console.log(event); //check event
resetAll(o);
}
});
}
function resetAll(o) {
/*<-
reset stuff here
->*/
//then start over again
setup(o);
}
return this.each(function() {
setup(obj);
checkProgress(obj);
});
};
})(jQuery);
Then i call the animation like this:
$(document).ready(function() {
$('#object').animation();
});
And then – nothing happens. No events get fired. My question: why? Is it not possible to use events like this inside of a jQuery plugin? Do I have to trigger them 'manualy' in $(document).ready() (what I would not prefer, because it would be a completely different thing – controling the animation from outside the plugin. Instead I would like to use the events inside the plugin to have a certain level of 'self-control' inside the plugin).
I feel like I'm missing some fundamental thing about custom events (note: I'm still quite new to this) and how to use them...
Thx for any help.
SOLUTION:
The event handling and triggering actually works, I just had to call the checkProgress function first:
Instead of
return this.each(function() {
setup(obj);
checkProgress(obj);
});
I had to do this:
return this.each(function() {
checkProgress(obj);
setup(obj);
});
So the event listening function has to be called before any event gets triggered, what of course makes perfect sense...
You need set event on your DOM model for instance:
$('#foo').bind('custom', function(event, param1, param2) {
alert('My trigger')
});
$('#foo').on('click', function(){ $(this).trigger('custom');});
You DOM element should know when he should fire your trigger.
Please note that in your plugin you don't call any internal function - ONLY DECLARATION