How do I delay javascript from executing after the click event? - javascript

programs! I've found solutions to similar problems such as mine here on the site but what's happening to me is rather unusual and I don't think they apply.
On this page: http://tdg.gswitchhost.com/calendar/
I'm locked into using this plugin which I really don't care for. This is a Wordpress site but the plugin, which lists upcoming events, doesn't behave like Wordpress. It has this system in place which is entirely unique to it. Posts live outside of the posts database table and you have to query these in an entirely different way. It's a bummer. So my problem:
We have some jquery working its magic on the events list to add an accordion effect and this works. However. When you click on the pagination links to load the next set of events, the plugin, instead of linking to page 2 of events, it runs an asynchronous query and loads the next set of events on to the existing page without a page reload. If you click on one of the new events, the accordion no longer works.
What I think is happening is that on click, the plugin removes the entire UL which contains the events and loads a second entirely new one, containing the second record set, with the same class name but since the javascript initialized on the first UL, the one the plugin removed, the new set hasn't been affected since the page didn't reload and run the javascript again.
I've tried using .on() and the Livequery plugin to rerun the javascript when you click the pagination links but there's a delay as the query is running and loading the new UL so I believe that the javascript runs again when you click on the link but because the UL hasn't been loaded already when you click, there's nothing for the jquery to work on.
Sorry this is so long but I just want to be as clear as possible. Am I wrong? This is killing me, I'm running out of time and I really need to get this to work so that no matter which set of events has been loaded on the page, the accordion function works on it.
Here's the javascript that initializes the accordion:
$('.eventListingNew').accordion({
headerClassName: 'accordionHeader',
headerActiveClassName: 'accordionHeader-active',
contentClassName: 'accordionContent',
collapseAll: false,
speed: 250
});
And here's a pastebin of the entire accordion function since it's so long. http://pastebin.com/BvDseg3g

Easy thing is just call it when the Ajax complete is done running to reinitialize it.
$(document).ajaxComplete(function(event, xhr, settings) {
$('.eventListingNew').accordion({
headerClassName: 'accordionHeader',
headerActiveClassName: 'accordionHeader-active',
contentClassName: 'accordionContent',
collapseAll: false,
speed: 250
});
});

Related

WordPress Blog - jQuery Issue

I have built a pretty simple WordPress blog however nearing the final stages I have run into a small problem that I cannot figure out for the life of me!
The site is http://lincsbusiness.co/, its running an ajax request so when you get the the bottom on the page its calls the next issues from the next page. Pretty simple.
However, if you follow these step you will be able to see the problem that I am talking about.
Refresh the home page
Expand the first issue, so you can see the sub headlines
Scroll to the bottom and till you get to issue 12
Try and expand that, and you will notice that the expansion bounces.
I am using the jQuery call back feature so after the AJAX request has finished it allows the jQuery to keep working.
And to stop having duplicate piece of jQuery for one before the event and one after, I have given the first four issue in the list unique identifiers, which are different to the one in the callback.
Here is the code I am using
jQuery(document.body).on('click', '.before-load', function(event) {
jQuery(this).closest('.thepost').find('.thepost-entry').slideToggle('slow');
});
And I use another piece, which is identical but just uses the '.after-load' class, just so I can separate them.
If you can replicate the issue and see whats going on, and have a potential fix. that would seriously save me my sanity.
Thanks
I have a feeling this is because you are re-adding the listener for the click each time you expand the page, so probably every time you load more posts, the next post you click bounces +1 times.
I'd recommend stopping any other jQuery execution, removing the 'click' handler, then letting the ajax call expand the page...and then re-adding the 'click' handler to each post.

Animate jQuery toggle only once per call

I have a pretty complex system with a few AJAX calls which render different templates into other templates in PHP.
One of these templates is a edit form for my entity. This form is rendered hidden into my website until a button was clicked, which will then fire a jQuery toggle() to switch out a part of my site for this edit form.
This works fine until the user is using the jQuery UI slider on my site.
What happens if the user navigates within the slider is that parts of my site will be reloaded with AJAX.
When the button for the toggle() then will be clicked the animation goes of as often as the slider was used (so if the slider was used 4 times the toggle will animate an switch out the 2 elements 4 times).
I debugged through it and couldn't find the mistake, i can't provide a jsFiddle which could rebuild the situation nor can i give access to the site. The click function will be fired only once, so i really can't explain why this is happening.
To mention is that i have 3 buttons which will trigger this event:
#poi_edit_ajax will be shown when the slider was used in the template which will be rendered per AJAX.
#poi_edit_first will be shown by first access to the site and nothing has been reloaded per AJAX.
#poi_edit_last will be shown so the user can come back from the edit view
The Javascript is the following:
$("#poi_edit_ajax").click(function(){
$(".toggle_edit").toggle('slow');
});
$("#poi_edit_first").click(function(){
$(".toggle_edit").toggle('slow');
});
$("#poi_edit_last").click(function(){
$(".toggle_edit").toggle('slow');
});
I don't think that somebody can give me a solution with just this information, but that's everything i can provide now, so my Question now is simply if it is possible to tell the toggle() function from jQuery to only run the animation ONCE PER CLICK.
I don't think that jQuery one() can be used for this, because so the click event could only be used once per pagevisit.
EDIT
According to the comment, i tried out if multiple event handlers will be registered within the AJAX calls, which is true.
The code to fix this is simple:
$("#comment_first").unbind("click").click(function(){
$('.toggle_information').toggle('slow');
});
$("#comment_last").unbind("click").click(function(){
$('.toggle_information').toggle('slow');
});
$("#comment_ajax").unbind("click").click(function(){
$('.toggle_information').toggle('slow');
});
I just need to unbind the Lister before bind it again, else they're gonna stuck and multiple Listeners will react to the click event!
You are probably binding the Click event multiple times (by loading javascript through the AJAX calls). Make sure you bind the Click handler (which triggers the toggle()) only once.
Take a look at this answer: https://stackoverflow.com/a/969011
A (slightly modified) quote from that answer, for quick reference:
function alertEvent() { alert("test"); }
$(".ajax").bind("click", alertEvent);
//When you want to ensure it won't happen twice...
$(".ajax").unbind("click", alertEvent);
$(".ajax").bind("click", alertEvent);
This method will only remove the event you specify

Remove all jQuery event handlers

I am creating a jQuery Mobile web app, which loads some pages.
For example, a.html is my main page. It may call b1.html,b2.html,...,b100.html (User may click on one of buttons). (The pages are loading with ajax navigation feature of jQuery Mobile)
And there is some events in each b[i].html page, and ids and many things are same in every b[i].html page. But the point is, at any time, just one of them may be in DOM. So there will be no id conflicts or such.
The problem
The problem is the conflict of the events. When user come back to a.html from b[i].html, the HTML will be removed, but events will remain. This will cause many problems if I first go to b[i].html, and then come back to a.html and then go to b[j].html. I mean, b[j].html will not work correctly... :(
What I have tried
I have putted this in a.html, to remove all events:
$("#mainpage").off("pagebeforeshow").on("pagebeforeshow",function() {
$("*").not("#mainpage").off();
//Other initialization codes...
});
But, problem not solved...
(mainpage is the id of data-role="page" of a.html)
Example
For example, I have this in each b[i].html:
$(window).resize(function () {
alert("Resized");
});
At the beginning (in a.html), If I resize the window, there will be no alerts, but after visiting b[i].html and then coming back to a.html, I'll see alerts if I resize the window, even with that line of code (What I have tried part.)...
So, How to remove those event handlers when users come back to a.html from b[i].html?
If you are using jQuery Mobile, more than one of said pages may exist in the dom at the same time, resulting in non-unique id conflicts.
I would ditch putting js on the individual pages and have it done from the primary page, or through a script loading system such as require.js. Then do all of the events through delegation from the document. Obviously that won't work with window.resize(), but it doesn't need to be delegated anyway.
"Can you please explain more?"
Basically, if you are including scripts on the child pages, you will need to have both setup and teardown for every page. setup adds the events, and teardown removes them. If you instead used a single global script that adds ALL of the events using event delegation from the document, all of the pages should work. Obviously that global script could get pretty big on a complex site, so you could instead use require.js to load in js that does the same thing as needed, preventing it from loading the same dependency more than once.
As far as removing all events, I've never tried this, but can you use $("*").off()? According to the docs it should work. I'm not sure how it will affect jQuery mobile. To remove events on the document and/or window, you will have to do it manually because $("*") will not select them.
$(document).on("vmousemove","#link",func) is how you delegate an event from the document.

jQuery/JavaScript Bind action after event jQuery UI Tabs

Just started a new job, working with the zend framework, the project is essentially complete its all patch work and adding onto the existing. However I came across a problem recently. The people who initially developed this project just seem to have bolted everything on top of everything on top of everything. So its messy, and its a major task in it of itself to find something to alter it in some way shape form or another.
What my current problem is, is the project is using datatables and jQuery UI. In this particular case I am working with a page that is "Tab" based. And I have multiple datatables on the page one under each tab. Problem is the datatable has to be redrawn on the tabs that are initially hidden on the page load as the tables don't conform to the element they reside in.
So the original developers have it somewhere in this system where? I can't find.. where they some how dynamically add $(#element).tabs({}) onto the page on a per page basis. Like I said its rather messy and overtly complicated the way they built this thing. So with that in mind I can't find the particular tabs function originally being called earlier in the page load so I can alter it to redraw the table on load.
So what I am wondering is, is there a way to catch a tabs event, that when it shows the tabs content I can just trigger off that event without having to alter the original call to tabs()?
I think the event you want to bind to is:
$( ".selector" ).bind( "tabsselect", function(event, ui) {
...
// Objects available in the function context:
ui.tab // anchor element of the selected (clicked) tab
ui.panel // element, that contains the selected/clicked tab contents
ui.index // zero-based index of the selected (clicked) tab
});
from JQuery UI

How do I hide all my label tags in my jQuery Mobile site in an accessibility friendly way?

I am trying to hide all the label tags on my jQuery Mobile site in an accessibility friendly way. To this end, I am using javascript to apply the class ui-hidden-accessible to every label tag on my site per documentation (http://jquerymobile.com/test/docs/forms/docs-forms.html).
However, my javascript is not working.
Here is a Fiddle demonstrating how the label tag still appears.
http://jsfiddle.net/tW4Xu/
Why is it not working? I have also scrutinized other jQM event handlers such as pageinit and pagecreate:
http://jquerymobile.com/test/docs/api/events.html
My javascript to hide label tags:
// done after page is loaded
$(document).on("pageshow", "label", function(event) {
$(this).addClass("ui-hidden-accessible");
});​
It seems like you have a few things going wrong here, although I'm not sure how much of it is coming from the jsfiddle summary and how much is in your full code.
The first thing to note is that 'pageshow' is a page transition event. It seems like you might want to use 'pageinit' instead. Here's how the jQM docs describe it:
Triggered on the page being initialized, after initialization occurs. We recommend binding to this event instead of DOM ready() because this will work regardless of whether the page is loaded directly or if the content is pulled into another page as part of the Ajax navigation system.
$( '#aboutPage' ).live( 'pageinit',function(event){
alert( 'This page was just enhanced by jQuery Mobile!' );
});
Note also here that 1) the event is being bound with live() instead of on() (no idea if there's a difference), and 2) it is being attached to a specific id for a jQM 'page'. This is part of what is missing in your jsfiddle example. There aren't any named jQM pages. jQM kind of messes up the whole idea of a page being ready, since everything is in one html file and then gets chunked out using ids and inserted via AJAX.
And so finally: Even though jQM says not to, if your goal is to add this class to every single label on every single jQM page, I would use good-old $(document).ready() and then use $.each() to change them all in one go. Again, from the jQM docs:
However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate, and the DOM ready handler only executes for the first page. To execute code whenever a new page is loaded and created, you can bind to the pageinit event.
So there isn't anything evil about $.ready(), it's just that this event is only fired once so subsequent page transitions won't trigger it. But that could be exactly what you want in the first place.
This code works on jsfiddle:
$(document).ready( function(event) {
$("label").each( function(index, element) {
element.addClass("ui-hidden-accessible");
});
});​
If in your real site you notice that page transitions cause the labels to come back, then you'll want to bind to something else, again probably 'pageinit'.
Hope this helps! Apologies for the verbosity...I kind of got going there huh?
http://jsfiddle.net/tW4Xu/2/
That? Not sure what your specific requirement is for using on('pageshow'), in my fiddle I used
$(function() {
$('label').addClass("ui-hidden-accessible");
});​
Don't use live its deprecated as of jquery 1.7. You had the right idea just do it before pageshow and make sure you use the page id. Also in your fiddle the top drop down menu change from onload to no wrap(head). I have had issues with that in the past.
$(document).on("pageinit", "#thepageid", function(event) {
$('label').addClass("ui-hidden-accessible");
});​
This will work for all your JQM pages.
$(document).on("pageinit", "[data-role=page]", function(event) {
$('label').addClass("ui-hidden-accessible");
});​

Categories