jQuery clearInterval issue - javascript

I'm working on a script to check if a file exists every 5s on onclick event. When it exists, I notify the client and reset the counter. First file check everything works fine, but when I check another file (click on another link with other data-file), it checks again both files and first file check is looping forever until I refresh the page. I tried everything I could think of, nothing worked. Please help!
var intervalCheck;
function isFileExists(file) {
$.ajax({
type: 'HEAD',
url: '/apps/'+file,
success: function() {
alert('found '+file);
clearInterval(intervalCheck);
},
error: function() {
}
});
}
$('#dialog').on('show.bs.modal', function(e) {
var file = $(e.relatedTarget).data('file');
$("a#checkfile").click(function() { intervalCheck = setInterval(function() { isFileExists(file); },5000); });
});

You must bind click event to only a#checkfile in clicked #dialog. Otherwise it will bind event to all a#checkfile elements. So when you open dialog for second time there will be 2 events on the a#checkfile link.
$(this).find('a#checkfile')
UPDATE
If there is one dialog contains multiple links, you can use jquery's one function for one-time events.
$('a#checkfile').one('click', function(){});

Related

How to restart the Jquery events, to avoid the repetition of each one of them?

I have an index page that contains the following events.
<div id="sub_page"></div>
$(document).ready(function () {
$("a.menu_navegacion_abrircaja").on('click', function (ev) {
ev.preventDefault();
var href = “nombrecontrollerEJ/view_ej";
$.post(href, function (data) {
$("#sub_page").html(data);
});
});
});
In it, when you click, load the html contents of subpages in the div sub_page.
In view view view_ej, I bring html code and also, jquery code. The Jquery code of the view that is added to the index div is as follows:
$(document).ready(function () {
$('#modal_establecer_turnos').on('hidden.bs.modal', function () {
alert("hello");
});
});
By clicking on the link that contains the class "menu_navegacion_abrircaja", I get the alert ("hello");
But it turns out that there is a problem, for every time I click on the link, the alert messages are repeated (alert ("hello");). For example, the first time I click on the link that contains the class menu_navegacion_abrircaja, it works fine showing the alert once, but then I click again on the same link it shows me the alert twice, then I do it for the third time, He shows me three times the alert, and so on.
I would like to know how to solve this problem.
Will there be any way to restart the events or handler of the jquery, as are the events click, change, "hidden.bs.modal", etc., in such a way that their repetition of the events is avoided?
I have seen the methods unbind (), bind (), off (), which might be the solution, but if so, how could you apply them?
Maybe you could try something like this in the jQuery code of your subpage:
$(document).ready(function () {
$('#modal_establecer_turnos').off('hidden.bs.modal');
$('#modal_establecer_turnos').on('hidden.bs.modal', function () {
alert(“hello”);
});
});

Magnific-Popup close callback does not execute

For each <a> that has mfp-ajax class will be executed as a pop-up box, and this pop-up box use the plugin in Magnific-Popup.
HTML:
View List
Javascript:
magnificSetting: {
type: 'ajax',
mainClass: 'mfp-fade',
ajax: {
settings: {
cache: false
}
}
},
modals: function () {
var self = this;
$('a.mfp-ajax').each(function () {
var $this = $(this);
$this.magnificPopup(self.settings.magnificSetting);
});
}
The codes works fine, however <a> is sometimes dynamically generated in the DOM and I have to create a separate script for Magnific-Popup callbacks. So what I did is I followed what is in the documentation, see the codes below:
$(document).on('mfpClose', '.multiselect-modal', function () {
console.log('test');
});
I tried this code but this does not get executed, how do I attach this in an element that is being generated dynamically in the DOM and when the pop-up opens and the user close it, it will go to the above code. Am I missing something here?
Unfortunately Magnific Popup internally uses triggerHandler() rather than trigger() to implement custom events ,so there is no event for the document to "listen to" so this may never work with current versions
$(document).on('mfpClose', '.multiselect-modal', function () {
console.log('test');
});
There is one fix but that requires you to create global events which is a bad practise so i advice you to make use of callbacks which is close in your case goes like this
$.magnificPopup.instance.close = function() {
//do your stuff here
//this calls the original close to close popup
//you may well comment it out which would totally disable the close button or execute conditional in if else
$.magnificPopup.proto.close.call();
};
these are some properties
//property
magnificPopup.currItem // current item
magnificPopup.index // current item index
// Navigation
magnificPopup.next(); // go to next item
magnificPopup.prev(); // go to prev item
magnificPopup.goTo(4); // go to slide #4

Ajax Load Event Incrementing By One

I have a simple textarea where users can input text which is then passed through via AJAX to a URL once they hit the return key. My issue is that on the first press of the return key the text data is sent once, on the second it's sent twice, and so on incrementing my one each time.
After some reading up I realise that if I was using a form submit I'd have to unbind it to prevent this happening. I've tried adding a value flag to prevent the multiple events, but have only got so far as to get it to trigger once only.
My code is as follows. Any guidance on how to prevent the incrementing events would be appreciated - as you can probably tell my confidence/knowledge in Javascript isn't the best. Thank you!
$(function() {
$("#myTextarea").keypress(function(e) {
// If the user hits the return key
if(e.which == 13) {
e.preventDefault();
$.ajax({
success: function(){
var modal = $('#myModal'), modalBody = $('#myModal .modal-body');
modal
// Load the webpage result within the modal Body
.on('show.bs.modal', function () {
modalBody.load('http://www.things.co.uk/things' + document.getElementById('myTextArea').value)
})
.modal();
// Hide the modal after five seconds
myModalTimeout = setTimeout(function() {
$('#myModal').modal('hide');
}, 5000);
}
});
}
});
});
Edit: I solved this by using one() for my modal event via http://www.andismith.com/blog/2011/11/on-and-off/. Thank you everyone.
You must attach the event handler only once. I suppose you're getting the JS in your AJAX response, and executing it again and again on each AJAX load. Removing and re-attaching the handlers is a hacky solution.
To avoid to attach the event handlers more than once, simply put your script in a part of the page which is not reloaded by AJAX, so the event is attached only once.
You can even attach an event handler to an element that is reloaded by ajax using delegated events: Understanding Event Delegation
With this technique, you attach the event handler to a container parent element which is not reloaded by ajax, and handle the events of the reloaded children specified by a filter.
$( "#container" ).on("<event>", "<children filter>", function( event ) {
// code to handle the event
});
Note that in this sample #container is the element which isn't reloaded by ajax. And <children filter> is a jquery selector that chooses the children whose event mus be handled. (<event> is obviously the event name, like click or keyPress).
Explanation: when the event is trigger in the child element, it pops up to the container. The container catches it, and checks that the children passes the filter. If so, the vent is handled.
If there are no more event handlers on myTextarea div code below should suffice.
If there are multiple event handlers attached to keypress event you will have to use named function and remove it using $.unbind() more on how to do this.
$(function() {
$("#myTextarea").off();
$("#myTextarea").keypress(function(e) {
// If the user hits the return key
if(e.which == 13) {
e.preventDefault();
$.ajax({
success: function(){
var modal = $('#myModal'), modalBody = $('#myModal .modal-body');
modal
// Load the webpage result within the modal Body
.on('show.bs.modal', function () {
modalBody.load('http://www.things.co.uk/things' + document.getElementById('myTextArea').value)
})
.modal();
// Hide the modal after five seconds
myModalTimeout = setTimeout(function() {
$('#myModal').modal('hide');
}, 5000);
}
});
}
});
});

mockjax loader - stop from running for specific function

I am making use of Jonathan Sampson's answer for my jquery busy loader. it works 100% and detects any jquery posting or the like and shows the loader.
my problem is that most times I want the user to wait when I fetch info from the database so happy for the loader to appear.
What I want however, is for certain functions only for the loader not to show when I save info to the database.
the fiddle can be found here
for example, the below causes the loader to run. how can I modify this so mockjax knows not to run for this function only?
$(document).on("click", function(){
$.get("/mockjax");
});
Thanks for the help as always.
Short version (with code)
Click the heading - Animation
Click the paragraph - No Animation
http://jsfiddle.net/hPS2v/
$.ajax({
url: "/mockjax",
type: "GET",
global: false //This is the key
});
--
The slightly longer version
There is a great variable available in the $.ajax() method which let's you stop ajax events from firing (but not the ajax itself). This is called global. From the docs
global (default: true)
Type: Boolean
Whether to trigger global Ajax
event handlers for this request. The default is true. Set to false to
prevent the global handlers like ajaxStart or ajaxStop from being
triggered. This can be used to control various Ajax Events.
With this in mind, I have slightly changed your code a little to demonstrate how we can make this work.
1) Moved the AJAX call into a function with 2 parameters: URL and eventTrigger. Basically we want the URL to be "/mockajax", and the eventTrigger to be true or false (depending on if and when you want to show your animation)
2) I took the event handler off the $(document) and added 2 events to the heading tags and the p tags so I can demonstrate the AJAX working in 2 places with the same code (1 with and 1 without an animation)
Hope this helps!
You can use a variable as a flag which denotes your preference of not showing the loader.
//let say, showLoader, by default true
var showLoader = true;
Now, add this to your ajax setup as required.
$(document).on({
ajaxStart: function () {
// if showLoader true, then shows loading image
if (showLoader)
$body.addClass("loading");
},
ajaxStop: function () {
$body.removeClass("loading");
// set showLoader to true
showLoader = true;
}
});
Change showLoader state as required by you.
$(document).on("click", function (e) {
// if target element is anchor tag, then do not show loading image - example
if (e.target.tagName === 'A') {
showLoader = false;
}
$.get("/mockjax");
});
JSFiddle: http://jsfiddle.net/VpDUG/5177/
Hope, it helps.

Multiple Jquery events on one page

I am quite new to Jquery and need help trying to get a few events to run on the same page. I have two sections of events, one is a .get which passes data to a file and then displays retrieved data, this happens on page load. The second section is on click events which send and receive data when a button is clicked.
These events all work as needed, but if I have both sections on one page the on click events do not work. Below is the code I have and I hope someone knows how to get them all to work? Thanks
<script type="text/javascript">
$.get("/layout/standard/check.php", { url: "domain"}, function(data){
$("#content-area").html(data)
});
$(".discuss").click( function() {
$.post('/layout/standard/report-action.php', {form: "discuss"},function(data){
$(".message").html(data);
$(".message").show("slow");
});
});
$(".request").click( function() {
$.post('/layout/standard/report-action.php', {form: "request"},function(data){
$(".message").html(data);
$(".message").show("slow");
});
});
$(".report").click( function() {
$.post('/layout/standard/report-action.php', {form: "report"},function(data){
$(".message").html(data);
$(".message").show("slow");
});
});
</script>
I believe that I have found why it's not working, the onclick links are put on the page by the get event. It would appear that the buttons work if they're already on the page but not if they are inserted this way.
This doesn't make sense to me as the buttons are still acting as links with no problem...
Try delegation.. and putting your code inside a document.ready function
$(function() {
$.get("/layout/standard/check.php", {
url: "domain"
}, function(data) {
$("#content-area").html(data)
});
$("body").on('click','.discuss,.request,.report',function() {
$.post('/layout/standard/report-action.php', {
form: $(this).attr('class') //this is assuming you only have 1 class per element
}, function(data) {
$(".message").html(data);
$(".message").show("slow");
});
});
});​
You might need to delegate the events if they are attached to content created dynamically. Try replacing:
$(".discuss").click( function() {
With:
$('body').on('click', '.discuss', function() {
And continue for all your events. You can replace the 'body' selector with another selector as long as it is always present in your document.

Categories